[libwnck] core: Use a destroy notify in hash tables to unref when removing item



commit 0dde8be271f19cfc2368aaf59f25a48f5ee51f08
Author: Vincent Untz <vuntz gnome org>
Date:   Mon Jan 30 14:18:22 2012 +0100

    core: Use a destroy notify in hash tables to unref when removing item
    
    We were manually unreferencing objects from hash tables when remove
    them, instead of using an automatic, and therefore safer, mechanism.

 libwnck/application.c |   44 ++++++++++++++++++--------------------------
 libwnck/class-group.c |   38 +++++++++++++-------------------------
 libwnck/window.c      |   18 ++++++++++--------
 3 files changed, 41 insertions(+), 59 deletions(-)
---
diff --git a/libwnck/application.c b/libwnck/application.c
index 9171549..edd32e6 100644
--- a/libwnck/application.c
+++ b/libwnck/application.c
@@ -99,6 +99,16 @@ static void wnck_application_finalize    (GObject        *object);
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+void
+_wnck_application_shutdown_all (void)
+{
+  if (app_hash != NULL)
+    {
+      g_hash_table_destroy (app_hash);
+      app_hash = NULL;
+    }
+}
+
 static void
 wnck_application_init (WnckApplication *application)
 {
@@ -522,7 +532,8 @@ _wnck_application_create (Window      xwindow,
   Screen          *xscreen;
 
   if (app_hash == NULL)
-    app_hash = g_hash_table_new (_wnck_xid_hash, _wnck_xid_equal);
+    app_hash = g_hash_table_new_full (_wnck_xid_hash, _wnck_xid_equal,
+                                      NULL, g_object_unref);
 
   g_return_val_if_fail (g_hash_table_lookup (app_hash, &xwindow) == NULL,
                         NULL);
@@ -566,14 +577,15 @@ _wnck_application_create (Window      xwindow,
 void
 _wnck_application_destroy (WnckApplication *application)
 {
-  g_return_if_fail (wnck_application_get (application->priv->xwindow) == application);
+  Window xwindow = application->priv->xwindow;
 
-  g_hash_table_remove (app_hash, &application->priv->xwindow);
+  g_return_if_fail (wnck_application_get (xwindow) == application);
 
-  g_return_if_fail (wnck_application_get (application->priv->xwindow) == NULL);
+  g_hash_table_remove (app_hash, &xwindow);
 
-  /* remove hash's ref on the application */
-  g_object_unref (G_OBJECT (application));
+  /* Removing from hash also removes the only ref WnckApplication had */
+
+  g_return_if_fail (wnck_application_get (xwindow) == NULL);
 }
 
 static void
@@ -677,26 +689,6 @@ _wnck_application_process_property_notify (WnckApplication *app,
 }
 
 static void
-_wnck_app_iter_destroy_application (gpointer key,
-                                    gpointer value,
-                                    gpointer user_data)
-{
-  g_object_unref (WNCK_APPLICATION (value));
-}
-
-void
-_wnck_application_shutdown_all (void)
-{
-  if (app_hash != NULL)
-    {
-      g_hash_table_foreach (app_hash, _wnck_app_iter_destroy_application, NULL);
-      g_hash_table_destroy (app_hash);
-      app_hash = NULL;
-    }
-}
-
-
-static void
 emit_name_changed (WnckApplication *app)
 {
   g_signal_emit (G_OBJECT (app),
diff --git a/libwnck/class-group.c b/libwnck/class-group.c
index 56e48d2..6676d49 100644
--- a/libwnck/class-group.c
+++ b/libwnck/class-group.c
@@ -80,6 +80,16 @@ enum {
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+void
+_wnck_class_group_shutdown_all (void)
+{
+  if (class_group_hash != NULL)
+    {
+      g_hash_table_destroy (class_group_hash);
+      class_group_hash = NULL;
+    }
+}
+
 static void
 wnck_class_group_class_init (WnckClassGroupClass *class)
 {
@@ -200,7 +210,8 @@ _wnck_class_group_create (const char *res_class)
   WnckClassGroup *class_group;
 
   if (class_group_hash == NULL)
-    class_group_hash = g_hash_table_new (g_str_hash, g_str_equal);
+    class_group_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                              NULL, g_object_unref);
 
   g_return_val_if_fail (g_hash_table_lookup (class_group_hash, res_class ? res_class : "") == NULL,
 			NULL);
@@ -229,11 +240,7 @@ _wnck_class_group_destroy (WnckClassGroup *class_group)
 
   g_hash_table_remove (class_group_hash, class_group->priv->res_class);
 
-  g_free (class_group->priv->res_class);
-  class_group->priv->res_class = NULL;
-
-  /* remove hash's ref on the class group */
-  g_object_unref (class_group);
+  /* Removing from hash also removes the only ref WnckClassGroup had */
 }
 
 static const char *
@@ -636,22 +643,3 @@ wnck_class_group_get_mini_icon (WnckClassGroup *class_group)
 
   return class_group->priv->mini_icon;
 }
-
-static void
-_wnck_class_iter_destroy_class_group (gpointer key,
-                                      gpointer value,
-                                      gpointer user_data)
-{
-  g_object_unref (WNCK_CLASS_GROUP (value));
-}
-
-void
-_wnck_class_group_shutdown_all (void)
-{
-  if (class_group_hash != NULL)
-    {
-      g_hash_table_foreach (class_group_hash, _wnck_class_iter_destroy_class_group, NULL);
-      g_hash_table_destroy (class_group_hash);
-      class_group_hash = NULL;
-    }
-}
diff --git a/libwnck/window.c b/libwnck/window.c
index 3c6584b..8d77a50 100644
--- a/libwnck/window.c
+++ b/libwnck/window.c
@@ -455,6 +455,8 @@ wnck_window_finalize (GObject *object)
   g_free (window->priv->res_name);
   window->priv->res_name = NULL;
 
+  window->priv->xwindow = None;
+
   G_OBJECT_CLASS (wnck_window_parent_class)->finalize (object);
 }
 
@@ -504,7 +506,8 @@ _wnck_window_create (Window      xwindow,
   Screen     *xscreen;
 
   if (window_hash == NULL)
-    window_hash = g_hash_table_new (_wnck_xid_hash, _wnck_xid_equal);
+    window_hash = g_hash_table_new_full (_wnck_xid_hash, _wnck_xid_equal,
+                                         NULL, g_object_unref);
 
   g_return_val_if_fail (g_hash_table_lookup (window_hash, &xwindow) == NULL,
                         NULL);
@@ -574,18 +577,17 @@ _wnck_window_create (Window      xwindow,
 void
 _wnck_window_destroy (WnckWindow *window)
 {
-  g_return_if_fail (WNCK_IS_WINDOW (window));
+  Window xwindow = window->priv->xwindow;
 
-  g_return_if_fail (wnck_window_get (window->priv->xwindow) == window);
+  g_return_if_fail (WNCK_IS_WINDOW (window));
 
-  g_hash_table_remove (window_hash, &window->priv->xwindow);
+  g_return_if_fail (wnck_window_get (xwindow) == window);
 
-  g_return_if_fail (wnck_window_get (window->priv->xwindow) == NULL);
+  g_hash_table_remove (window_hash, &xwindow);
 
-  window->priv->xwindow = None;
+  /* Removing from hash also removes the only ref WnckWindow had */
 
-  /* remove hash's ref on the window */
-  g_object_unref (G_OBJECT (window));
+  g_return_if_fail (wnck_window_get (xwindow) == NULL);
 }
 
 void



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