Apply workaround for Wayland set_queue race
authorDavid Harvey-Macaulay <david.harvey-macaulay@arm.com>
Mon, 15 Mar 2021 15:46:32 +0000 (15:46 +0000)
committerDavid Harvey-Macaulay <david.harvey-macaulay@arm.com>
Thu, 8 Apr 2021 12:08:56 +0000 (13:08 +0100)
commit5b6fe3301fb316f65f83a66ec8cfcfb22ae6fbf1
tree25b7a2633f6b9e9c573cf074d7cf6e02e54b1309
parent7c3a626118e6d99fd9871fef46c8e2c7ef1a83b1
Apply workaround for Wayland set_queue race

Wayland objects receive events from the server into an event queue.
Unless specified otherwise, events from the server arrive to the event
queue belonging to the parent object. It is beneficial for us to
override this default queue assignment so that we receive only the
events we are interested in.

We currently override the default event queue assignment using
wl_proxy_set_queue after object construction:

struct wl_object *child_object = wl_create_object(parent_object);
wl_proxy_set_queue((struct wl_proxy *)child_object, queue);

There is a race condition here: events may be received into the parent's
queue before we have a chance to perform this override. This will lead
to hangs if we are expecting an event to arrive to our specific queue.
To workaround this issue, we can use a wrapper object to specify the
desired event queue at the time of object creation:

struct wl_object *parent_wrapper = wl_proxy_create_wrapper(parent_object);
wl_proxy_set_queue((struct wl_proxy *)parent_wrapper, queue);
struct wl_object *child_object = wl_create_object(parent_wrapper);
wl_proxy_wrapper_destroy(parent_wrapper);

This commit applies this workaround to all object allocations whose
intended event queues differ from the default assignment to avoid the
aforementioned race condition.

Change-Id: I3e6a7c679280f0d66b02ab7eab06a010e9e24b36
Signed-off-by: David Harvey-Macaulay <david.harvey-macaulay@arm.com>
wsi/wayland/swapchain.cpp