[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