[gtk/fix-icontheme-invalidation: 5/18] icon-theme: Fix deadlock in GktIconTheme dispose



commit e75bc2833dbf40d8c50ff6ade4c8f868e62f5305
Author: Alexander Larsson <alexl redhat com>
Date:   Wed Apr 22 14:20:33 2020 +0200

    icon-theme: Fix deadlock in GktIconTheme dispose
    
    When freeing the display GtkIconTheme and that was the last owner we
    ran into a deadlock, because we unref the "next-to-last" ref inside a
    gtk_icon_theme_ref_aquire/release() pair, which makes the final unref
    to happen in the release(), while the ref lock still was held.
    The unref triggers dispose which tries to NULL out the ref, but that then
    deadlocks on the mutex being held by the caller already.
    
    We fix this by moving the release unref outside the lock. This is safe
    because refcounts are atomic, and we *do* own the ref.

 gtk/gtkicontheme.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkicontheme.c b/gtk/gtkicontheme.c
index c8e5eaaa50..cce4706c95 100644
--- a/gtk/gtkicontheme.c
+++ b/gtk/gtkicontheme.c
@@ -549,9 +549,16 @@ gtk_icon_theme_ref_aquire (GtkIconThemeRef *ref)
 static void
 gtk_icon_theme_ref_release (GtkIconThemeRef *ref)
 {
-  if (ref->theme)
-    g_object_unref (ref->theme);
+  GtkIconTheme *theme;
+
+  /* Get a pointer to the theme, becuse when we unlock it could become NULLed by dispose, this pointer still 
owns a ref */
+  theme = ref->theme;
   g_mutex_unlock (&ref->lock);
+
+  /* Then unref outside the lock, because otherwis if this is the last ref the dispose handler would 
deadlock trying to NULL ref->theme */
+  if (theme)
+    g_object_unref (theme);
+
 }
 
 static void


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]