[grilo] core: Free registry resources before unreffing it



commit 5520b4e219d9a9e1dd66aefcd27b2bda2d040a8e
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Sun Mar 2 01:24:03 2014 +0000

    core: Free registry resources before unreffing it
    
    We can't unref the registry to finalize all the sources and plugins, because
    they can try to access the registry again in their finalize method.
    
    This commit first finalizes the sources, plugins, and other resources, and at
    the end it unrefs the registry.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=724660

 src/grilo.c             |    2 +-
 src/grl-registry-priv.h |    2 +
 src/grl-registry.c      |  141 +++++++++++++++++++++++------------------------
 3 files changed, 72 insertions(+), 73 deletions(-)
---
diff --git a/src/grilo.c b/src/grilo.c
index 3207221..4f6ed24 100644
--- a/src/grilo.c
+++ b/src/grilo.c
@@ -181,7 +181,7 @@ grl_deinit (void)
   }
 
   registry = grl_registry_get_default ();
-  g_object_unref (registry);
+  grl_registry_shutdown (registry);
 }
 
 /**
diff --git a/src/grl-registry-priv.h b/src/grl-registry-priv.h
index 4ea3f58..9bdb562 100644
--- a/src/grl-registry-priv.h
+++ b/src/grl-registry-priv.h
@@ -34,4 +34,6 @@ GrlKeyID grl_registry_register_metadata_key_full (GrlRegistry *registry,
                                                   GrlKeyID key,
                                                   GError **error);
 
+void grl_registry_shutdown (GrlRegistry *registry);
+
 #endif /* _GRL_REGISTRY_PRIV_H_ */
diff --git a/src/grl-registry.c b/src/grl-registry.c
index 29a5374..cbbf600 100644
--- a/src/grl-registry.c
+++ b/src/grl-registry.c
@@ -87,8 +87,6 @@ struct _GrlRegistryPrivate {
   struct KeyIDHandler key_id_handler;
 };
 
-static void grl_registry_finalize (GObject *object);
-
 static void grl_registry_setup_ranks (GrlRegistry *registry);
 
 static void grl_registry_preload_plugins (GrlRegistry *registry,
@@ -123,14 +121,8 @@ G_DEFINE_TYPE (GrlRegistry, grl_registry, G_TYPE_OBJECT);
 static void
 grl_registry_class_init (GrlRegistryClass *klass)
 {
-  GObjectClass *gobject_klass;
-
   g_type_class_add_private (klass, sizeof (GrlRegistryPrivate));
 
-  gobject_klass = G_OBJECT_CLASS (klass);
-
-  gobject_klass->finalize = grl_registry_finalize;
-
   /**
    * GrlRegistry::source-added:
    * @registry: the registry
@@ -191,70 +183,6 @@ grl_registry_init (GrlRegistry *registry)
   grl_registry_setup_ranks (registry);
 }
 
-static void
-grl_registry_finalize (GObject *object)
-{
-  GHashTableIter iter;
-  GList *each_key;
-  GList *related_keys = NULL;
-  GrlPlugin *plugin = NULL;
-  GrlRegistry *registry = GRL_REGISTRY (object);
-  GrlSource *source = NULL;
-
-  if (registry->priv->sources) {
-    g_hash_table_iter_init (&iter, registry->priv->sources);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &source)) {
-      g_object_unref (source);
-    }
-    g_hash_table_unref (registry->priv->sources);
-    registry->priv->sources = NULL;
-  }
-
-  if (registry->priv->plugins) {
-    g_hash_table_iter_init (&iter, registry->priv->plugins);
-    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &plugin)) {
-      shutdown_plugin (plugin);
-    }
-    g_hash_table_unref (registry->priv->plugins);
-    registry->priv->plugins = NULL;
-  }
-
-  if (registry->priv->ranks) {
-    g_hash_table_unref (registry->priv->ranks);
-    registry->priv->configs = NULL;
-  }
-
-  if (registry->priv->configs) {
-    g_hash_table_unref (registry->priv->configs);
-    registry->priv->configs = NULL;
-  }
-
-  /* We need to free this table with care. Several keys can be pointing to the
-     same value, so we need to ensure that we only free the value once */
-  if (registry->priv->related_keys) {
-    while (TRUE) {
-      g_hash_table_iter_init (&iter, registry->priv->related_keys);
-      if (!g_hash_table_iter_next (&iter, NULL, (gpointer *) &related_keys)) {
-        break;
-      }
-      /* This will invalidate the iterator */
-      for (each_key = related_keys; each_key; each_key = g_list_next (each_key)) {
-        g_hash_table_remove (registry->priv->related_keys, GRLKEYID_TO_POINTER (each_key->data));
-      }
-      g_list_free (related_keys);
-    }
-    g_hash_table_unref (registry->priv->related_keys);
-    registry->priv->related_keys = NULL;
-  }
-
-  g_slist_free_full (registry->priv->plugins_dir, (GDestroyNotify) g_free);
-  g_slist_free_full (registry->priv->allowed_plugins, (GDestroyNotify) g_free);
-
-  key_id_handler_free (&registry->priv->key_id_handler);
-
-  G_OBJECT_CLASS (grl_registry_parent_class)->finalize (object);
-}
-
 /* ================ Utitilies ================ */
 
 static void
@@ -717,6 +645,75 @@ grl_registry_restrict_plugins (GrlRegistry *registry,
   }
 }
 
+/*
+ * grl_registry_shutdown:
+ * @registry: the registry instance
+ *
+ * Frees all the resources in the registry and the registry itself.
+ **/
+void
+grl_registry_shutdown (GrlRegistry *registry)
+{
+  GHashTableIter iter;
+  GList *each_key;
+  GList *related_keys = NULL;
+  GrlPlugin *plugin = NULL;
+  GrlSource *source = NULL;
+
+  if (registry->priv->plugins) {
+    g_hash_table_iter_init (&iter, registry->priv->plugins);
+    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &plugin)) {
+      shutdown_plugin (plugin);
+    }
+    g_hash_table_unref (registry->priv->plugins);
+    registry->priv->plugins = NULL;
+  }
+
+  if (registry->priv->sources) {
+    g_hash_table_iter_init (&iter, registry->priv->sources);
+    while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &source)) {
+      g_object_unref (source);
+    }
+    g_hash_table_unref (registry->priv->sources);
+    registry->priv->sources = NULL;
+  }
+
+  if (registry->priv->ranks) {
+    g_hash_table_unref (registry->priv->ranks);
+    registry->priv->configs = NULL;
+  }
+
+  if (registry->priv->configs) {
+    g_hash_table_unref (registry->priv->configs);
+    registry->priv->configs = NULL;
+  }
+
+  /* We need to free this table with care. Several keys can be pointing to the
+     same value, so we need to ensure that we only free the value once */
+  if (registry->priv->related_keys) {
+    while (TRUE) {
+      g_hash_table_iter_init (&iter, registry->priv->related_keys);
+      if (!g_hash_table_iter_next (&iter, NULL, (gpointer *) &related_keys)) {
+        break;
+      }
+      /* This will invalidate the iterator */
+      for (each_key = related_keys; each_key; each_key = g_list_next (each_key)) {
+        g_hash_table_remove (registry->priv->related_keys, GRLKEYID_TO_POINTER (each_key->data));
+      }
+      g_list_free (related_keys);
+    }
+    g_hash_table_unref (registry->priv->related_keys);
+    registry->priv->related_keys = NULL;
+  }
+
+  g_slist_free_full (registry->priv->plugins_dir, (GDestroyNotify) g_free);
+  g_slist_free_full (registry->priv->allowed_plugins, (GDestroyNotify) g_free);
+
+  key_id_handler_free (&registry->priv->key_id_handler);
+
+  g_object_unref (registry);
+}
+
 /* ================ PUBLIC API ================ */
 
 /**


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