[glib/wip/gcleanup: 37/78] gobject: Cleanup GObject class stuff



commit 7bee1f142e00f76ac2c6862d094a7ca51925659c
Author: Stef Walter <stefw gnome org>
Date:   Thu Nov 7 22:53:31 2013 +0100

    gobject: Cleanup GObject class stuff
    
    Initial work by: Dan Winship <danw gnome org>
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711778

 gobject/gobject.c       |   41 +++++++++++++++++++++++++++++++++++------
 gobject/gparam.c        |    7 +++++++
 gobject/gsignal.c       |   21 +++++++++++++++++++++
 gobject/gtype-private.h |    3 +++
 4 files changed, 66 insertions(+), 6 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 4fb9439..4cdd80e 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -199,6 +199,7 @@ static GQuark                   quark_weak_refs = 0;
 static GQuark              quark_toggle_refs = 0;
 static GQuark               quark_notify_queue;
 static GQuark               quark_in_construction;
+static GQuark               quark_interface_pspecs;
 static GParamSpecPool      *pspec_pool = NULL;
 static gulong              gobject_signals[LAST_SIGNAL] = { 0, };
 static guint (*floating_flag_handler) (GObject*, gint) = object_floating_flag_handler;
@@ -343,6 +344,9 @@ debug_objects_atexit (void)
 {
   IF_DEBUG (OBJECTS)
     {
+      if (debug_objects_ht == NULL)
+        return; /* deinitialized, do nothing */
+
       G_LOCK (debug_objects);
       g_message ("stale GObjects: %u", debug_objects_count);
       g_hash_table_foreach (debug_objects_ht, debug_objects_foreach, NULL);
@@ -397,6 +401,7 @@ _g_object_type_init (void)
   IF_DEBUG (OBJECTS)
     {
       debug_objects_ht = g_hash_table_new (g_direct_hash, NULL);
+      G_CLEANUP_IN_PHASE (debug_objects_ht, g_hash_table_unref, G_CLEANUP_PHASE_GRAVEYARD);
 #ifndef G_HAS_CONSTRUCTORS
       g_atexit (debug_objects_atexit);
 #endif /* G_HAS_CONSTRUCTORS */
@@ -422,15 +427,11 @@ g_object_base_class_init (GObjectClass *class)
 }
 
 static void
-g_object_base_class_finalize (GObjectClass *class)
+_g_object_type_free_pspecs (GType type)
 {
   GList *list, *node;
-  
-  _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
 
-  g_slist_free (class->construct_properties);
-  class->construct_properties = NULL;
-  list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class));
+  list = g_param_spec_pool_list_owned (pspec_pool, type);
   for (node = list; node; node = node->next)
     {
       GParamSpec *pspec = node->data;
@@ -443,6 +444,17 @@ g_object_base_class_finalize (GObjectClass *class)
 }
 
 static void
+g_object_base_class_finalize (GObjectClass *class)
+{
+  _g_signals_destroy (G_OBJECT_CLASS_TYPE (class));
+
+  g_slist_free (class->construct_properties);
+  class->construct_properties = NULL;
+
+  _g_object_type_free_pspecs (G_OBJECT_CLASS_TYPE (class));
+}
+
+static void
 g_object_do_class_init (GObjectClass *class)
 {
   /* read the comment about typedef struct CArray; on why not to change this quark */
@@ -453,7 +465,9 @@ g_object_do_class_init (GObjectClass *class)
   quark_toggle_refs = g_quark_from_static_string ("GObject-toggle-references");
   quark_notify_queue = g_quark_from_static_string ("GObject-notify-queue");
   quark_in_construction = g_quark_from_static_string ("GObject-in-construction");
+  quark_interface_pspecs = g_quark_from_static_string ("GObject-interface-pspecs");
   pspec_pool = g_param_spec_pool_new (TRUE);
+  G_CLEANUP_IN_PHASE (pspec_pool, _g_param_spec_pool_cleanup, G_CLEANUP_PHASE_LATE);
 
   class->constructor = g_object_constructor;
   class->constructed = g_object_constructed;
@@ -695,6 +709,14 @@ g_object_class_install_properties (GObjectClass  *oclass,
     }
 }
 
+static void
+free_interface_type_pspecs (gpointer data)
+{
+  GType type = GPOINTER_TO_SIZE (data);
+
+  _g_object_type_free_pspecs (type);
+}
+
 /**
  * g_object_interface_install_property:
  * @g_iface: any interface vtable for the interface, or the default
@@ -736,6 +758,13 @@ g_object_interface_install_property (gpointer      g_iface,
     g_return_if_fail (pspec->flags & G_PARAM_WRITABLE);
 
   install_property_internal (iface_class->g_type, 0, pspec);
+
+  if (!g_type_get_qdata (iface_class->g_type, quark_interface_pspecs))
+    {
+      g_type_set_qdata_full (iface_class->g_type, quark_interface_pspecs,
+                             GSIZE_TO_POINTER (iface_class->g_type),
+                             free_interface_type_pspecs);
+    }
 }
 
 /**
diff --git a/gobject/gparam.c b/gobject/gparam.c
index 10ee4dc..47f4e01 100644
--- a/gobject/gparam.c
+++ b/gobject/gparam.c
@@ -922,6 +922,13 @@ g_param_spec_pool_new (gboolean type_prefixing)
   return pool;
 }
 
+void
+_g_param_spec_pool_cleanup (GParamSpecPool *pool)
+{
+  g_hash_table_unref (pool->hash_table);
+  g_free (pool);
+}
+
 /**
  * g_param_spec_pool_insert:
  * @pool: a #GParamSpecPool.
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index ebdf8d9..49f3a48 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -821,6 +821,25 @@ signal_key_cmp (gconstpointer node1,
     return G_BSEARCH_ARRAY_CMP (key1->itype, key2->itype);
 }
 
+static void
+signal_cleanup (void)
+{
+  gint i;
+
+  /*
+   * Actual deep contents should have been destroyed by _g_signals_destroy()
+   * calls done earlier.
+   */
+
+  for (i = 1; i < g_n_signal_nodes; i++)
+    g_free (g_signal_nodes[i]);
+  g_free (g_signal_nodes);
+
+  g_bsearch_array_free (g_signal_key_bsa, &g_signal_key_bconfig);
+
+  g_hash_table_unref (g_handler_list_bsa_ht);
+}
+
 void
 _g_signal_init (void)
 {
@@ -835,6 +854,8 @@ _g_signal_init (void)
       g_n_signal_nodes = 1;
       g_signal_nodes = g_renew (SignalNode*, g_signal_nodes, g_n_signal_nodes);
       g_signal_nodes[0] = NULL;
+
+      G_CLEANUP_FUNC_IN_PHASE (signal_cleanup, G_CLEANUP_PHASE_GRAVEYARD);
     }
   SIGNAL_UNLOCK ();
 }
diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h
index d9e31e4..737985f 100644
--- a/gobject/gtype-private.h
+++ b/gobject/gtype-private.h
@@ -25,6 +25,7 @@
 
 #include "gboxed.h"
 #include "gclosure.h"
+#include "gparam.h"
 
 G_BEGIN_DECLS
 
@@ -74,6 +75,8 @@ void        _g_closure_invoke_va (GClosure       *closure,
 
 gboolean    g_type_is_in_init    (GType type);
 
+void        _g_param_spec_pool_cleanup  (GParamSpecPool *pool);
+
 G_END_DECLS
 
 #endif /* __G_TYPE_PRIVATE_H__ */


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