diff options
author | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2023-02-15 10:10:26 -0500 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2023-02-16 15:55:47 +0000 |
commit | 91de576a7f67c953b7a69fd45e1eb3b2a0dde996 (patch) | |
tree | 6b1bb2e0d32d24e91033348b2c1513bd8887a1d8 /src/loader | |
parent | 4621ffdec12436c36629399b8a5c259a1618180b (diff) | |
download | mesa-91de576a7f67c953b7a69fd45e1eb3b2a0dde996.tar.gz |
dri3: avoid deadlocking when polling deleted windows for events
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 <ajax@redhat.com>
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
Acked-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21339>
Diffstat (limited to 'src/loader')
-rw-r--r-- | src/loader/loader_dri3_helper.c | 17 |
1 files changed, 13 insertions, 4 deletions
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; } } } |