summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Høgsberg <krh@bitplanet.net>2014-02-08 00:50:50 (GMT)
committerKristian Høgsberg <krh@bitplanet.net>2014-02-08 00:50:50 (GMT)
commitb9eebce0aa5559855d835e403ba3bb5960baaadc (patch)
tree63c72a800e13a322acebeb9f4049cd1d0241cfdd
parenta9eb563fb7aa194ac3a29f335d0a1ae3dcdb72ee (diff)
downloadwayland-b9eebce0aa5559855d835e403ba3bb5960baaadc.tar.gz
wayland-b9eebce0aa5559855d835e403ba3bb5960baaadc.tar.xz
client: Queue display events on private queue and always dispatch
The wl_display events (error and delete_id) need to be handled even if the default queue doesn't get dispatched for a while. For example, a busy EGL rendering loop hits wl_display.sync every eglSwapBuffers() and we need to process the delete_id events to maintain the object ID data structure. As it is, that doesn't happen, but with this change we special case wl_display events. We put them on a custom, private queue and when dispatching events, we always dispatch display_queue events first. The wl_display proxy should still be the default_queue, so that objects created from wl_display requests get assigned to that.
-rw-r--r--src/wayland-client.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/wayland-client.c b/src/wayland-client.c
index 04b5115..208bc9c 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -83,6 +83,7 @@ struct wl_display {
int fd;
pthread_t display_thread;
struct wl_map objects;
+ struct wl_event_queue display_queue;
struct wl_event_queue default_queue;
struct wl_list event_queue_list;
pthread_mutex_t mutex;
@@ -713,6 +714,7 @@ wl_display_connect_to_fd(int fd)
display->fd = fd;
wl_map_init(&display->objects, WL_MAP_CLIENT_SIDE);
wl_event_queue_init(&display->default_queue, display);
+ wl_event_queue_init(&display->display_queue, display);
wl_list_init(&display->event_queue_list);
pthread_mutex_init(&display->mutex, NULL);
pthread_cond_init(&display->reader_cond, NULL);
@@ -931,6 +933,7 @@ queue_event(struct wl_display *display, int len)
struct wl_proxy *proxy;
struct wl_closure *closure;
const struct wl_message *message;
+ struct wl_event_queue *queue;
wl_connection_copy(display->connection, p, sizeof p);
id = p[0];
@@ -968,9 +971,14 @@ queue_event(struct wl_display *display, int len)
proxy->refcount++;
closure->proxy = proxy;
- if (wl_list_empty(&proxy->queue->event_list))
- pthread_cond_signal(&proxy->queue->cond);
- wl_list_insert(proxy->queue->event_list.prev, &closure->link);
+ if (proxy == &display->proxy)
+ queue = &display->display_queue;
+ else
+ queue = proxy->queue;
+
+ if (wl_list_empty(&queue->event_list))
+ pthread_cond_signal(&queue->cond);
+ wl_list_insert(queue->event_list.prev, &closure->link);
return size;
}
@@ -1143,10 +1151,19 @@ dispatch_queue(struct wl_display *display, struct wl_event_queue *queue)
if (display->last_error)
goto err;
- for (count = 0; !wl_list_empty(&queue->event_list); count++) {
+ count = 0;
+ while (!wl_list_empty(&display->display_queue.event_list)) {
+ dispatch_event(display, &display->display_queue);
+ if (display->last_error)
+ goto err;
+ count++;
+ }
+
+ while (!wl_list_empty(&queue->event_list)) {
dispatch_event(display, queue);
if (display->last_error)
goto err;
+ count++;
}
return count;