[Mesa-dev] [PATCH] vulkan/wsi: Avoid waiting indefinitely for present completion in x11_manage_fifo_queues().

Fredrik Höglund fredrik at kde.org
Tue Oct 24 14:11:22 UTC 2017


On Tuesday 17 October 2017, Henri Verbeet wrote:
> In particular, if the window was destroyed before the present request
> completed, xcb_wait_for_special_event() may never return.
> 
> Note that the usage of xcb_poll_for_special_event() requires a version
> of libxcb that includes commit fad81b63422105f9345215ab2716c4b804ec7986
> to work properly.
> 
> Signed-off-by: Henri Verbeet <hverbeet at gmail.com>
> ---
> This applies on top of "vulkan/wsi: Free the event in x11_manage_fifo_queues()."
> ---
>  src/vulkan/wsi/wsi_common_x11.c | 19 ++++++++++++++++---
>  1 file changed, 16 insertions(+), 3 deletions(-)
> 
> diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
> index 22b067b..ceb0d66 100644
> --- a/src/vulkan/wsi/wsi_common_x11.c
> +++ b/src/vulkan/wsi/wsi_common_x11.c
> @@ -908,10 +908,14 @@ static void *
>  x11_manage_fifo_queues(void *state)
>  {
>     struct x11_swapchain *chain = state;
> +   struct pollfd pfds;
>     VkResult result;
>  
>     assert(chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR);
>  
> +   pfds.fd = xcb_get_file_descriptor(chain->conn);
> +   pfds.events = POLLIN;
> +
>     while (chain->status == VK_SUCCESS) {
>        /* It should be safe to unconditionally block here.  Later in the loop
>         * we blocks until the previous present has landed on-screen.  At that
> @@ -934,9 +938,18 @@ x11_manage_fifo_queues(void *state)
>  
>        while (chain->last_present_msc < target_msc) {
>           xcb_generic_event_t *event =
> -            xcb_wait_for_special_event(chain->conn, chain->special_event);
> -         if (!event)
> -            goto fail;
> +            xcb_poll_for_special_event(chain->conn, chain->special_event);
> +         if (!event) {
> +            int ret = poll(&pfds, 1, 100);

There is a race condition here where another thread can read the event
from the file descriptor in the time between the calls to
xcb_poll_for_special_event() and poll().

I think what is really needed here is an
xcb_wait_for_special_event_with_timeout().

> +            if (ret < 0) {
> +               result = VK_ERROR_OUT_OF_DATE_KHR;
> +               goto fail;
> +            } else if (chain->status != VK_SUCCESS) {
> +               return NULL;
> +            }
> +
> +            continue;
> +         }
>  
>           result = x11_handle_dri3_present_event(chain, (void *)event);
>           free(event);
> 



More information about the mesa-dev mailing list