[PATCH wayland 4/4] client: Fix wl_display_roundtrip_queue() race condition
Pekka Paalanen
ppaalanen at gmail.com
Fri Apr 29 13:06:53 UTC 2016
On Wed, 27 Apr 2016 13:42:14 +0300
Pekka Paalanen <ppaalanen at gmail.com> wrote:
> On Wed, 27 Apr 2016 15:37:41 +0800
> Jonas Ådahl <jadahl at gmail.com> wrote:
>
> > 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 <jadahl at gmail.com>
> > ---
> > src/wayland-client.c | 10 ++++++++--
> > 1 file changed, 8 insertions(+), 2 deletions(-)
> >
> > diff --git a/src/wayland-client.c b/src/wayland-client.c
> > index 6de91cd..cb5213b 100644
> > --- a/src/wayland-client.c
> > +++ b/src/wayland-client.c
> > @@ -1106,14 +1106,20 @@ 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);
>
> Check display_wrapper.
>
> > + 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);
>
> Then:
> Reviewed-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
>
I added the check and pushed:
69ec70f..6fe12f0 master -> master
Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 811 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20160429/d645fc0f/attachment-0001.sig>
More information about the wayland-devel
mailing list