client: Add wl_display_dispatch_pending() for dispatching without reading
authorKristian Høgsberg <krh@bitplanet.net>
Thu, 11 Oct 2012 21:15:08 +0000 (17:15 -0400)
committerKristian Høgsberg <krh@bitplanet.net>
Mon, 15 Oct 2012 14:52:53 +0000 (10:52 -0400)
If the main thread ends up dispatching a non-main queue, and not in
a wl_display_dispatch() callback, we may queue up main queue events and read
all data from the socket fd.  When we get back to the main loop, the
socket fd is no longer readable and nothing will trigger dispatching of
the queued up events.

The new function wl_display_dispatch_pending() will dispatch any pending
events, but not attempt to read from the socket.  Clients that integrate
the wayland socket fd into a main loop should call
wl_display_dispatch_pending() and then wl_display_flush()
before going back to blocking in poll(2) or similar mechanism.

src/wayland-client.c
src/wayland-client.h

index 8ced6cc..9077338 100644 (file)
@@ -552,9 +552,9 @@ dispatch_event(struct wl_display *display, struct wl_event_queue *queue)
 }
 
 
-WL_EXPORT int
-wl_display_dispatch_queue(struct wl_display *display,
-                         struct wl_event_queue *queue)
+static int
+dispatch_queue(struct wl_display *display,
+              struct wl_event_queue *queue, int block)
 {
        int len, size;
 
@@ -563,7 +563,7 @@ wl_display_dispatch_queue(struct wl_display *display,
        /* FIXME: Handle flush errors, EAGAIN... */
        wl_connection_flush(display->connection);
 
-       if (wl_list_empty(&queue->event_list) &&
+       if (block && wl_list_empty(&queue->event_list) &&
            pthread_equal(display->display_thread, pthread_self())) {
                len = wl_connection_read(display->connection);
                if (len == -1) {
@@ -576,7 +576,7 @@ wl_display_dispatch_queue(struct wl_display *display,
                                break;
                        len -= size;
                }
-       } else if (wl_list_empty(&queue->event_list)) {
+       } else if (block && wl_list_empty(&queue->event_list)) {
                pthread_cond_wait(&queue->cond, &display->mutex);
        }
 
@@ -589,11 +589,26 @@ wl_display_dispatch_queue(struct wl_display *display,
 }
 
 WL_EXPORT int
+wl_display_dispatch_queue(struct wl_display *display,
+                         struct wl_event_queue *queue)
+{
+       return dispatch_queue(display, queue, 1);
+}
+
+WL_EXPORT int
 wl_display_dispatch(struct wl_display *display)
 {
        display->display_thread = pthread_self();
 
-       return wl_display_dispatch_queue(display, &display->queue);
+       return dispatch_queue(display, &display->queue, 1);
+}
+
+WL_EXPORT int
+wl_display_dispatch_pending(struct wl_display *display)
+{
+       display->display_thread = pthread_self();
+
+       return dispatch_queue(display, &display->queue, 0);
 }
 
 WL_EXPORT int
index cb1be9c..a73566e 100644 (file)
@@ -60,6 +60,7 @@ int wl_display_get_fd(struct wl_display *display);
 int wl_display_dispatch(struct wl_display *display);
 int wl_display_dispatch_queue(struct wl_display *display,
                              struct wl_event_queue *queue);
+int wl_display_dispatch_pending(struct wl_display *display);
 
 int wl_display_flush(struct wl_display *display);
 void wl_display_roundtrip(struct wl_display *display);