[Xfce4-commits] [xfce/thunar] 02/02: Don't call g_object_ref/unref on objects that are being finalized.

noreply at xfce.org noreply at xfce.org
Thu Feb 9 00:08:48 CET 2017


This is an automated email from the git hooks/post-receive script.

ochosi pushed a commit to branch master
in repository xfce/thunar.

commit 35e65ab0ed5675b2dc7b4224b0ad152df3c3e9b0
Author: John Lindgren <john.lindgren at aol.com>
Date:   Fri Jun 17 02:50:52 2016 -0400

    Don't call g_object_ref/unref on objects that are being finalized.
    
    ThunarFile objects were not being removed from the file_cache until
    thunar_file_finalize().  This leaves a small window of time in which
    another thread might call thunar_file_get(), and fetch the partially
    finalized ThunarFile from the cache.
    
    There are likely some remaining thread-safety issues with ThunarFile,
    due to background jobs making changes to the same objects that are used
    simultaneously in the UI thread.
---
 thunar/thunar-file.c | 56 ++++++++++++++++++++++++++++++++++------------------
 1 file changed, 37 insertions(+), 19 deletions(-)

diff --git a/thunar/thunar-file.c b/thunar/thunar-file.c
index ccca2c9..c2a89d8 100644
--- a/thunar/thunar-file.c
+++ b/thunar/thunar-file.c
@@ -221,6 +221,22 @@ G_DEFINE_TYPE_WITH_CODE (ThunarFile, thunar_file, G_TYPE_OBJECT,
     G_IMPLEMENT_INTERFACE (THUNARX_TYPE_FILE_INFO, thunar_file_info_init))
 
 
+static GWeakRef*
+weak_ref_new (GObject *obj)
+{
+  GWeakRef *ref;
+  ref = g_slice_new (GWeakRef);
+  g_weak_ref_init (ref, obj);
+  return ref;
+}
+
+static void
+weak_ref_free (GWeakRef *ref)
+{
+  g_weak_ref_clear (ref);
+  g_slice_free (GWeakRef, ref);
+}
+
 
 #ifdef G_ENABLE_DEBUG
 #ifdef HAVE_ATEXIT
@@ -236,7 +252,7 @@ thunar_file_atexit_foreach (gpointer key,
   gchar *uri;
 
   uri = g_file_get_uri (key);
-  g_print ("--> %s (%u)\n", uri, G_OBJECT (value)->ref_count);
+  g_print ("--> %s\n", uri);
   if (G_OBJECT (key)->ref_count > 2)
     g_print ("    GFile (%u)\n", G_OBJECT (key)->ref_count - 2);
   g_free (uri);
@@ -278,7 +294,7 @@ thunar_file_cache_dump_foreach (gpointer gfile,
   gchar *name;
 
   name = g_file_get_parse_name (G_FILE (gfile));
-  g_print ("    %s (%u)\n", name, G_OBJECT (value)->ref_count);
+  g_print ("    %s\n", name);
   g_free (name);
 }
 
@@ -729,7 +745,9 @@ thunar_file_monitor_moved (ThunarFile *file,
   g_object_unref (previous_file);
 
   /* insert the new entry */
-  g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
+  g_hash_table_insert (file_cache,
+                       g_object_ref (file->gfile),
+                       weak_ref_new (G_OBJECT (file)));
 
   G_UNLOCK (file_cache_mutex);
 }
@@ -1122,11 +1140,9 @@ thunar_file_get_async_finish (GObject      *object,
 
   /* insert the file into the cache */
   G_LOCK (file_cache_mutex);
-#ifdef G_ENABLE_DEBUG
-  /* check if there is no instance created in the meantime */
-  _thunar_assert (g_hash_table_lookup (file_cache, file->gfile) == NULL);
-#endif
-  g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
+  g_hash_table_insert (file_cache,
+                       g_object_ref (file->gfile),
+                       weak_ref_new (G_OBJECT (file)));
   G_UNLOCK (file_cache_mutex);
 
   /* pass the loaded file and possible errors to the return function */
@@ -1248,7 +1264,9 @@ thunar_file_get (GFile   *gfile,
           G_LOCK (file_cache_mutex);
 
           /* insert the file into the cache */
-          g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
+          g_hash_table_insert (file_cache,
+                               g_object_ref (file->gfile),
+                               weak_ref_new (G_OBJECT (file)));
 
           /* done inserting in the cache */
           G_UNLOCK (file_cache_mutex);
@@ -1325,7 +1343,9 @@ thunar_file_get_with_info (GFile     *gfile,
       G_LOCK (file_cache_mutex);
 
       /* insert the file into the cache */
-      g_hash_table_insert (file_cache, g_object_ref (file->gfile), file);
+      g_hash_table_insert (file_cache,
+                           g_object_ref (file->gfile),
+                           weak_ref_new (G_OBJECT (file)));
 
       /* done inserting in the cache */
       G_UNLOCK (file_cache_mutex);
@@ -4096,6 +4116,7 @@ thunar_file_same_filesystem (const ThunarFile *file_a,
 ThunarFile *
 thunar_file_cache_lookup (const GFile *file)
 {
+  GWeakRef   *ref;
   ThunarFile *cached_file;
 
   _thunar_return_val_if_fail (G_IS_FILE (file), NULL);
@@ -4108,18 +4129,15 @@ thunar_file_cache_lookup (const GFile *file)
       file_cache = g_hash_table_new_full (g_file_hash, 
                                           (GEqualFunc) g_file_equal, 
                                           (GDestroyNotify) g_object_unref, 
-                                          NULL);
+                                          (GDestroyNotify) weak_ref_free);
     }
 
-  cached_file = g_hash_table_lookup (file_cache, file);
+  ref = g_hash_table_lookup (file_cache, file);
 
-  if (cached_file != NULL)
-    {
-      /* take a reference to avoid too-early releases outside the
-       * file_cache_mutex, resuling in destroyed files being used
-       * in running code */
-      g_object_ref (cached_file);
-    }
+  if (ref == NULL)
+    cached_file = NULL;
+  else
+    cached_file = g_weak_ref_get (ref);
 
   G_UNLOCK (file_cache_mutex);
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list