summaryrefslogtreecommitdiff
path: root/src/loader
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2023-02-15 10:10:26 -0500
committerMarge Bot <emma+marge@anholt.net>2023-02-16 15:55:47 +0000
commit91de576a7f67c953b7a69fd45e1eb3b2a0dde996 (patch)
tree6b1bb2e0d32d24e91033348b2c1513bd8887a1d8 /src/loader
parent4621ffdec12436c36629399b8a5c259a1618180b (diff)
downloadmesa-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.c17
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;
}
}
}