From 6fe12f02e3b4879cd3d5faa08f023cc761d13be9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jonas=20=C3=85dahl?= Date: Wed, 27 Apr 2016 15:37:41 +0800 Subject: [PATCH] client: Fix wl_display_roundtrip_queue() race condition MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Without this commit, wl_display_roundtrip_queue() is vulnerable to a race condition, causing the callback to be dispatched on the wrong queue. The race condition happens if some non-main thread calls wl_display_roundtrip_queue() with its thread local queue, and the main thread reads and dispatches the callback event from the wl_display_sync() call before the thread local queue is set. The issue is fixed by using a proxy wrapper, making the initialization of the callback proxy atomic, effectively making it no longer possible for some other thread to dispatch the proxy before the correct thread local queue is set. Signed-off-by: Jonas Ådahl [Pekka: check display_wrapper] Signed-off-by: Pekka Paalanen --- src/wayland-client.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/wayland-client.c b/src/wayland-client.c index 867adea..7af806c 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -1099,14 +1099,23 @@ static const struct wl_callback_listener sync_listener = { WL_EXPORT int wl_display_roundtrip_queue(struct wl_display *display, struct wl_event_queue *queue) { + struct wl_display *display_wrapper; struct wl_callback *callback; int done, ret = 0; done = 0; - callback = wl_display_sync(display); + + display_wrapper = wl_proxy_create_wrapper(display); + if (!display_wrapper) + return -1; + + wl_proxy_set_queue((struct wl_proxy *) display_wrapper, queue); + callback = wl_display_sync(display_wrapper); + wl_proxy_wrapper_destroy(display_wrapper); + if (callback == NULL) return -1; - wl_proxy_set_queue((struct wl_proxy *) callback, queue); + wl_callback_add_listener(callback, &sync_listener, &done); while (!done && ret >= 0) ret = wl_display_dispatch_queue(display, queue); -- 2.7.4