From 3da62fdd2848bd9d06b83534adfee2afa17828ba Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 5 Oct 2007 13:41:39 +0100 Subject: [PATCH] [cairo-xlib-display] Rescan the displays list during shutdown. As we drop the list mutex whilst calling the hooks during the XCloseDisplay callback, we must rescan the list when we reacquire the mutex in order to remove the display from the list. --- src/cairo-xlib-display.c | 48 ++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index 83170f597..d77b64f3a 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -158,6 +158,8 @@ _cairo_xlib_display_destroy (cairo_xlib_display_t *display) _cairo_freelist_fini (&display->wq_freelist); _cairo_freelist_fini (&display->hook_freelist); + CAIRO_MUTEX_FINI (display->mutex); + free (display); } @@ -171,6 +173,29 @@ static int _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) { cairo_xlib_display_t *display, **prev, *next; + cairo_xlib_error_func_t old_handler; + + CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); + for (display = _cairo_xlib_display_list; display; display = display->next) + if (display->display == dpy) + break; + CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); + if (display == NULL) + return 0; + + /* protect the notifies from triggering XErrors */ + XSync (dpy, False); + old_handler = XSetErrorHandler (_noop_error_handler); + + _cairo_xlib_display_notify (display); + _cairo_xlib_call_close_display_hooks (display); + _cairo_xlib_display_discard_screens (display); + + /* catch any that arrived before marking the display as closed */ + _cairo_xlib_display_notify (display); + + XSync (dpy, False); + XSetErrorHandler (old_handler); /* * Unhook from the global list @@ -180,27 +205,6 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) for (display = _cairo_xlib_display_list; display; display = next) { next = display->next; if (display->display == dpy) { - cairo_xlib_error_func_t old_handler; - - /* drop the list mutex whilst triggering the hooks */ - CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); - - /* protect the notifies from triggering XErrors */ - XSync (dpy, False); - old_handler = XSetErrorHandler (_noop_error_handler); - - _cairo_xlib_display_notify (display); - _cairo_xlib_call_close_display_hooks (display); - _cairo_xlib_display_discard_screens (display); - - /* catch any that arrived before marking the display as closed */ - _cairo_xlib_display_notify (display); - - XSync (dpy, False); - XSetErrorHandler (old_handler); - - CAIRO_MUTEX_LOCK (_cairo_xlib_display_mutex); - _cairo_xlib_display_destroy (display); *prev = next; break; } else @@ -208,6 +212,8 @@ _cairo_xlib_close_display (Display *dpy, XExtCodes *codes) } CAIRO_MUTEX_UNLOCK (_cairo_xlib_display_mutex); + _cairo_xlib_display_destroy (display); + /* Return value in accordance with requirements of * XESetCloseDisplay */ return 0;