[PATCH wayland] client: ensure thread safety for wl_display_roundtrip_queue()
Ucan, Emre (ADITG/SW1)
eucan at de.adit-jv.com
Mon Feb 15 14:19:43 UTC 2016
We have to block other threads from reading events. Otherwise other threads
may assign done event to the default queue, if they call
wl_display_read_events before setting the queue for the callback proxy.
This would cause a deadlock in wl_display_dispatch_queue,
because the default queue is not dispatched.
We can call wl_display_prepare_read_queue API which blocks on success
other threads from reading events and call wl_display_cancel read after
the queue is set to the proxy. This new implementation ensures thread
safety for the API.
Signed-off-by: Emre Ucan <eucan at de.adit-jv.com>
---
src/wayland-client.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/wayland-client.c b/src/wayland-client.c
index ef12bfc..00d8cda 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -1075,12 +1075,26 @@ wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue *qu
struct wl_callback *callback;
int done, ret = 0;
+ /*We have to block other threads from reading events. Otherwise other threads
+ * may assign done event to the default queue, if they call wl_display_read_events
+ * before setting the queue for the callback proxy. This would cause a deadlock
+ * in wl_display_dispatch_queue, because the default queue is not dispatched.*/
+ while (ret >= 0 && wl_display_prepare_read_queue(display, queue))
+ ret = wl_display_dispatch_queue_pending(display, queue);
+
+ if (ret < 0)
+ return ret;
+
done = 0;
callback = wl_display_sync(display);
- if (callback == NULL)
+ if (callback == NULL) {
+ wl_display_cancel_read(display);
return -1;
+ }
+
wl_proxy_set_queue((struct wl_proxy *) callback, queue);
wl_callback_add_listener(callback, &sync_listener, &done);
+ wl_display_cancel_read(display);
while (!done && ret >= 0)
ret = wl_display_dispatch_queue(display, queue);
--
1.7.9.5
More information about the wayland-devel
mailing list