From 91de576a7f67c953b7a69fd45e1eb3b2a0dde996 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 15 Feb 2023 10:10:26 -0500 Subject: dri3: avoid deadlocking when polling deleted windows for events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit upcoming xserver releases will emit PresentConfigureNotify with this flag set when a window is destroyed, ensuring drivers don't poll infinitely and deadlock Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/116 cc: mesa-stable Reviewed-by: Adam Jackson Reviewed-by: Michel Dänzer Acked-by: Daniel Stone Part-of: --- src/loader/loader_dri3_helper.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'src/loader') diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index 3c4534709b7..63be04ed2a4 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -478,16 +478,24 @@ loader_dri3_drawable_init(xcb_connection_t *conn, return 0; } +/* XXX this belongs in presentproto */ +#ifndef PresentWindowDestroyed +#define PresentWindowDestroyed (1 << 0) +#endif /* * Process one Present event */ -static void +static bool dri3_handle_present_event(struct loader_dri3_drawable *draw, xcb_present_generic_event_t *ge) { switch (ge->evtype) { case XCB_PRESENT_CONFIGURE_NOTIFY: { xcb_present_configure_notify_event_t *ce = (void *) ge; + if (ce->pixmap_flags & PresentWindowDestroyed) { + free(ge); + return false; + } draw->width = ce->width; draw->height = ce->height; @@ -563,6 +571,7 @@ dri3_handle_present_event(struct loader_dri3_drawable *draw, } } free(ge); + return true; } static bool @@ -596,8 +605,7 @@ dri3_wait_for_event_locked(struct loader_dri3_drawable *draw, if (full_sequence) *full_sequence = ev->full_sequence; ge = (void *) ev; - dri3_handle_present_event(draw, ge); - return true; + return dri3_handle_present_event(draw, ge); } /** loader_dri3_wait_for_msc @@ -980,7 +988,8 @@ dri3_flush_present_events(struct loader_dri3_drawable *draw) while ((ev = xcb_poll_for_special_event(draw->conn, draw->special_event)) != NULL) { xcb_present_generic_event_t *ge = (void *) ev; - dri3_handle_present_event(draw, ge); + if (!dri3_handle_present_event(draw, ge)) + break; } } } -- cgit v1.2.1