[cairo-commit] 2 commits - src/cairo-xlib-screen.c src/cairo-xlib-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Apr 12 13:44:21 PDT 2007


 src/cairo-xlib-screen.c  |   33 ++++++++++++++++++++++++---------
 src/cairo-xlib-surface.c |   10 ++++++----
 2 files changed, 30 insertions(+), 13 deletions(-)

New commits:
diff-tree 35bb2152c06ef2621b14a8b2153cc327be8b43a1 (from 97d897a7475f540ad901cb2a2cd6885e885ee02a)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 12 21:30:39 2007 +0100

    Hold the scaled_font->mutex whilst operating on the shared members.
    
    Obey the locking rules whilst resetting the scaled_font after a
    CloseDisplay.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index bfee1c7..55f95bb 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -2309,16 +2309,18 @@ _cairo_xlib_surface_remove_scaled_font (
 	                               void    *data)
 {
     cairo_scaled_font_t *scaled_font = data;
-    cairo_xlib_surface_font_private_t	*font_private = scaled_font->surface_private;
+    cairo_xlib_surface_font_private_t	*font_private;
+
+    CAIRO_MUTEX_LOCK (scaled_font->mutex);
+    font_private  = scaled_font->surface_private;
+    scaled_font->surface_private = NULL;
 
     _cairo_scaled_font_reset_cache (scaled_font);
+    CAIRO_MUTEX_UNLOCK (scaled_font->mutex);
 
-    /* separate function to avoid deadlock if we tried to remove the
-     * close display hook ala _cairo_xlib_surface_scaled_font_fini() */
     if (font_private) {
 	XRenderFreeGlyphSet (font_private->dpy, font_private->glyphset);
 	free (font_private);
-	scaled_font->surface_private = NULL;
     }
 }
 
diff-tree 97d897a7475f540ad901cb2a2cd6885e885ee02a (from 13b0aa669fd9ce6abc930730a941782e2baba215)
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Apr 12 21:17:42 2007 +0100

    cairo_xlib_close_display - drop the mutex whilst calling the hooks
    
    In order to avoid recursive dead-locks where whilst one thread holds the
    scaled font lock and is waiting on the XLockDisplay() another thread catches
    the CloseDisplay and then tries to acquire the scaled font lock, we drop
    the list mutex whilst processing the callbacks.

diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c
index 749ad4e..f79cb49 100644
--- a/src/cairo-xlib-screen.c
+++ b/src/cairo-xlib-screen.c
@@ -244,6 +244,29 @@ _cairo_xlib_init_screen_font_options (ca
 
 static cairo_xlib_screen_info_t *_cairo_xlib_screen_list = NULL;
 
+/* NOTE: This function must be called with _cairo_xlib_screen_mutex held. */
+static void
+_cairo_xlib_call_close_display_hooks (cairo_xlib_screen_info_t *info)
+{
+    /* call all registered shutdown routines */
+    while (info->close_display_hooks != NULL) {
+	cairo_xlib_hook_t *hooks = info->close_display_hooks;
+	info->close_display_hooks = NULL;
+
+	/* drop the list mutex whilst calling the hooks */
+	CAIRO_MUTEX_UNLOCK (_cairo_xlib_screen_mutex);
+	do {
+	    cairo_xlib_hook_t *hook = hooks;
+	    hooks = hook->next;
+
+	    hook->func (info->display, hook->data);
+
+	    free (hook);
+	} while (hooks != NULL);
+	CAIRO_MUTEX_LOCK (_cairo_xlib_screen_mutex);
+    }
+}
+
 static int
 _cairo_xlib_close_display (Display *dpy, XExtCodes *codes)
 {
@@ -258,16 +281,8 @@ _cairo_xlib_close_display (Display *dpy,
     for (info = _cairo_xlib_screen_list; info; info = next) {
 	next = info->next;
 	if (info->display == dpy) {
+	    _cairo_xlib_call_close_display_hooks (info);
 	    *prev = next;
-	    /* call all registered shutdown routines */
-	    while (info->close_display_hooks) {
-		cairo_xlib_hook_t *hook = info->close_display_hooks;
-		info->close_display_hooks = hook->next;
-
-		hook->func (dpy, hook->data);
-
-		free (hook);
-	    }
 	    free (info);
 	} else {
 	    prev = &info->next;


More information about the cairo-commit mailing list