[glib/wip/free: 3/6] get gobject working, except for dynamic types



commit 5e7bfe1faae48134b3525d18685049dc8d643d9c
Author: Dan Winship <danw gnome org>
Date:   Tue Aug 28 20:40:07 2012 -0400

    get gobject working, except for dynamic types

 gobject/gatomicarray.c      |   50 +++++----
 gobject/gatomicarray.h      |    3 +-
 gobject/gobject.c           |   24 ++--
 gobject/gparam.c            |    8 +-
 gobject/gparamspecs.c       |    5 +-
 gobject/gsignal.c           |   11 +-
 gobject/gtype-private.h     |    6 +
 gobject/gtype.c             |  254 ++++++++++++++++++++++---------------------
 gobject/gvalue.c            |    2 +-
 gobject/tests/enums.c       |    4 +
 gobject/tests/signals.c     |    3 +
 gobject/tests/threadtests.c |   24 ++++-
 12 files changed, 215 insertions(+), 179 deletions(-)
---
diff --git a/gobject/gatomicarray.c b/gobject/gatomicarray.c
index d341cab..fcf162a 100644
--- a/gobject/gatomicarray.c
+++ b/gobject/gatomicarray.c
@@ -102,30 +102,6 @@ _g_atomic_array_init (GAtomicArray *array)
   array->data = NULL;
 }
 
-void
-_g_atomic_array_free (GAtomicArray *array)
-{
-  if (array->data != NULL)
-    freelist_free (array->data);
-}
-
-void
-_g_atomic_array_deinit (void)
-{
-  FreeListNode *cur, *next;
-
-  for (cur = freelist; cur; cur = next)
-    {
-      gsize size, real_size;
-
-      next = cur->next;
-
-      size = G_ATOMIC_ARRAY_DATA_SIZE (cur);
-      real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
-      g_slice_free1 (real_size, ((char *) cur) - sizeof (gsize));
-    }
-}
-
 /* Get a copy of the data (if non-NULL) that
  * can be changed and then re-applied with
  * g_atomic_array_update().
@@ -193,3 +169,29 @@ _g_atomic_array_update (GAtomicArray *array,
     freelist_free (old);
   G_UNLOCK (array);
 }
+
+void
+_g_atomic_array_free (GAtomicArray *array)
+{
+  if (array->data != NULL)
+    freelist_free (array->data);
+}
+
+void
+_g_atomic_array_cleanup (void)
+{
+  FreeListNode *cur, *next;
+
+  for (cur = freelist; cur; cur = next)
+    {
+      gsize size, real_size;
+
+      next = cur->next;
+
+      size = G_ATOMIC_ARRAY_DATA_SIZE (cur);
+      real_size = G_ATOMIC_ARRAY_REAL_SIZE_FROM (size);
+      g_slice_free1 (real_size, ((char *) cur) - sizeof (gsize));
+    }
+
+  g_mutex_clear (&G_LOCK_NAME (array));
+}
diff --git a/gobject/gatomicarray.h b/gobject/gatomicarray.h
index 8a8e8b8..f27c9c3 100644
--- a/gobject/gatomicarray.h
+++ b/gobject/gatomicarray.h
@@ -36,7 +36,6 @@ struct _GAtomicArray {
 
 void     _g_atomic_array_init   (GAtomicArray *array);
 void     _g_atomic_array_free   (GAtomicArray *array);
-void     _g_atomic_array_deinit (void);
 gpointer _g_atomic_array_copy   (GAtomicArray *array,
                                 gsize         header_size,
                                 gsize         additional_element_size);
@@ -57,6 +56,8 @@ void     _g_atomic_array_update (GAtomicArray *array,
     } while (transaction_data != __check);                                     \
   } G_STMT_END
 
+void _g_atomic_array_cleanup (void);
+
 G_END_DECLS
 
 #endif /* __G_ATOMIC_ARRAY_H__ */
diff --git a/gobject/gobject.c b/gobject/gobject.c
index e47d0f9..80a652e 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -407,21 +407,19 @@ _g_object_type_init (void)
 }
 
 void
-g_object_type_deinit (void)
+_g_object_type_cleanup (void)
 {
-  if (pspec_pool != NULL)
-    {
-      g_param_spec_pool_destroy (pspec_pool);
-      pspec_pool = NULL;
-    }
-
+  g_clear_pointer (&pspec_pool, g_param_spec_pool_destroy);
 #ifdef G_ENABLE_DEBUG
-  if (debug_objects_ht != NULL)
-    {
-      g_hash_table_unref (debug_objects_ht);
-      debug_objects_ht = NULL;
-    }
-#endif /* G_ENABLE_DEBUG */
+  g_clear_pointer (&debug_objects_ht, g_hash_table_unref);
+#endif
+
+  g_mutex_clear (&G_LOCK_NAME (closure_array_mutex));
+  g_mutex_clear (&G_LOCK_NAME (weak_refs_mutex));
+  g_mutex_clear (&G_LOCK_NAME (toggle_refs_mutex));
+  g_mutex_clear (&G_LOCK_NAME (construction_mutex));
+  g_mutex_clear (&G_LOCK_NAME (notify_lock));
+  g_rw_lock_clear (&weak_locations_lock);
 }
 
 static void
diff --git a/gobject/gparam.c b/gobject/gparam.c
index 9e9a8af..6fe9d10 100644
--- a/gobject/gparam.c
+++ b/gobject/gparam.c
@@ -131,11 +131,12 @@ _g_param_type_init (void)
 }
 
 void
-g_param_type_deinit (void)
+_g_param_type_cleanup (void)
 {
-  g_slist_foreach (g_param_spec_class_info, (GFunc) g_free, NULL);
-  g_slist_free (g_param_spec_class_info);
+  g_slist_free_full (g_param_spec_class_info, g_free);
   g_param_spec_class_info = NULL;
+
+  g_mutex_clear (&G_LOCK_NAME (g_param_spec_class_info));
 }
 
 static void
@@ -921,6 +922,7 @@ g_param_spec_pool_destroy (GParamSpecPool *pool)
   while (g_hash_table_iter_next (&iter, &key, NULL))
     g_param_spec_unref (key);
   g_hash_table_unref (pool->hash_table);
+  g_mutex_clear (&pool->mutex);
 
   g_free (pool);
 }
diff --git a/gobject/gparamspecs.c b/gobject/gparamspecs.c
index f44c808..9ed869b 100644
--- a/gobject/gparamspecs.c
+++ b/gobject/gparamspecs.c
@@ -1593,10 +1593,9 @@ _g_param_spec_types_init (void)
 }
 
 void
-g_param_spec_types_deinit (void)
+_g_param_spec_types_cleanup (void)
 {
-  g_free (g_param_spec_types);
-  g_param_spec_types = NULL;
+  g_clear_pointer (&g_param_spec_types, g_free);
 }
 
 /* --- GParamSpec initialization --- */
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index 6741f22..a72a345 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -832,7 +832,7 @@ _g_signal_init (void)
 }
 
 void
-g_signal_deinit (void)
+_g_signal_cleanup (void)
 {
   guint i;
 
@@ -848,17 +848,14 @@ g_signal_deinit (void)
     }
 
   SIGNAL_UNLOCK ();
+  g_mutex_clear (&G_LOCK_NAME (g_signal_mutex));
 
-  g_hash_table_unref (g_handler_list_bsa_ht);
-  g_handler_list_bsa_ht = NULL;
+  g_clear_pointer (&g_handler_list_bsa_ht, g_hash_table_unref);
 
   g_bsearch_array_free (g_signal_key_bsa, &g_signal_key_bconfig);
   g_signal_key_bsa = NULL;
 
-  g_n_signal_nodes = 0;
-
-  g_free (g_signal_nodes);
-  g_signal_nodes = NULL;
+  g_clear_pointer (&g_signal_nodes, g_free);
 }
 
 void
diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h
index fac8fec..f385dec 100644
--- a/gobject/gtype-private.h
+++ b/gobject/gtype-private.h
@@ -51,6 +51,12 @@ void    _g_param_spec_types_init (void); /* sync with gparamspecs.c */
 void    _g_value_transforms_init (void); /* sync with gvaluetransform.c */
 void    _g_signal_init           (void); /* sync with gsignal.c */
 
+void    _g_value_c_cleanup          (void); /* sync with gvalue.c */
+void    _g_param_type_cleanup       (void); /* sync with gparam.c */
+void    _g_object_type_cleanup      (void); /* sync with gobject.c */
+void    _g_param_spec_types_cleanup (void); /* sync with gparamspecs.c */
+void    _g_signal_cleanup           (void); /* sync with gsignal.c */
+
 /* for gboxed.c */
 gpointer        _g_type_boxed_copy      (GType          type,
                                          gpointer       value);
diff --git a/gobject/gtype.c b/gobject/gtype.c
index 1e00363..6c62bc2 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -32,7 +32,7 @@
 #include "gbsearcharray.h"
 #include "gatomicarray.h"
 #include "gobject_trace.h"
-
+#include "gconstructor.h"
 
 /**
  * SECTION:gtype
@@ -4257,6 +4257,8 @@ _g_type_boxed_init (GType          type,
 }
 
 /* --- initialization --- */
+G_LOCK_DEFINE_STATIC (type_init_lock);
+
 /**
  * g_type_init_with_debug_flags:
  * @debug_flags: Bitwise combination of #GTypeDebugFlags values for
@@ -4269,7 +4271,6 @@ _g_type_boxed_init (GType          type,
 void
 g_type_init_with_debug_flags (GTypeDebugFlags debug_flags)
 {
-  G_LOCK_DEFINE_STATIC (type_init_lock);
   const gchar *env_string;
   GTypeInfo info;
   TypeNode *node;
@@ -4452,7 +4453,6 @@ type_data_finalize_class (TypeNode  *node,
 static void
 type_data_finalize (TypeNode *node)
 {
-  GType ptype = NODE_PARENT_TYPE (node);
   TypeData *tdata;
 
   tdata = node->data;
@@ -4480,126 +4480,6 @@ type_data_finalize (TypeNode *node)
     }
 }
 
-void
-g_type_deinit (void)
-{
-  GHashTableIter iter;
-  gpointer value;
-  GHashTable * vtables;
-
-  g_hash_table_iter_init (&iter, static_type_nodes_ht);
-  while (g_hash_table_iter_next (&iter, NULL, &value))
-    {
-      GType gtype = (GType) GPOINTER_TO_SIZE (value);
-      TypeNode *node;
-
-      node = lookup_type_node_I (gtype);
-      if (node->is_classed)
-        type_data_finalize (node);
-    }
-
-  g_hash_table_iter_init (&iter, static_type_nodes_ht);
-  while (g_hash_table_iter_next (&iter, NULL, &value))
-    {
-      GType gtype = (GType) GPOINTER_TO_SIZE (value);
-      TypeNode *node;
-
-      node = lookup_type_node_I (gtype);
-      if (NODE_IS_IFACE (node))
-        type_data_finalize (node);
-    }
-
-  g_signal_deinit ();
-
-  g_param_spec_types_deinit ();
-
-  g_object_type_deinit ();
-
-  g_param_type_deinit ();
-
-  g_value_c_deinit ();
-
-  static_n_class_cache_funcs = 0;
-  g_free (static_class_cache_funcs);
-  static_class_cache_funcs = NULL;
-
-  static_n_iface_check_funcs = 0;
-  g_free (static_iface_check_funcs);
-  static_iface_check_funcs = NULL;
-
-  g_hash_table_iter_init (&iter, static_type_nodes_ht);
-  vtables = g_hash_table_new (NULL, NULL);
-  while (g_hash_table_iter_next (&iter, NULL, &value))
-    {
-      GType gtype = (GType) GPOINTER_TO_SIZE (value);
-      TypeNode *node;
-
-      node = lookup_type_node_I (gtype);
-
-      g_free (node->children);
-
-      if (node->is_classed)
-        {
-          IFaceEntries *entries;
-
-          entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
-          if (entries)
-           {
-              guint i;
-
-             for (i = 0; i != IFACE_ENTRIES_N_ENTRIES (entries); i++)
-               g_hash_table_insert (vtables, entries->entry[i].vtable, NULL);
-            }
-
-          _g_atomic_array_free (CLASSED_NODE_IFACES_ENTRIES (node));
-
-          if (node->data != NULL)
-            g_free (node->data->class.class);
-        }
-
-      if (NODE_IS_IFACE (node))
-        {
-          IFaceHolder *iholder, *next;
-
-          _g_atomic_array_free (&node->_prot.offsets);
-
-          iholder = iface_node_get_holders_L (node);
-          while (iholder)
-            {
-              next = iholder->next;
-
-              g_free (iholder->info);
-              g_free (iholder);
-
-              iholder = next;
-            }
-
-          if (node->data != NULL)
-            g_free (node->data->iface.dflt_vtable);
-
-          g_free (iface_node_get_dependants_array_L (node));
-        }
-
-      g_free (node->data);
-
-      if (node->global_gdata != NULL)
-        g_free (node->global_gdata->qdatas);
-      g_free (node->global_gdata);
-
-      g_free (node->prerequisites);
-
-      if (G_TYPE_IS_FUNDAMENTAL (gtype))
-        node = G_STRUCT_MEMBER_P (node, -SIZEOF_FUNDAMENTAL_INFO);
-      g_free (node);
-    }
-  g_hash_table_foreach (vtables, (GHFunc) g_free, NULL);
-  g_hash_table_unref (vtables);
-  g_hash_table_unref (static_type_nodes_ht);
-  static_type_nodes_ht = NULL;
-
-  _g_atomic_array_deinit ();
-}
-
 /**
  * g_type_class_add_private:
  * @g_class: class structure for an instantiatable type
@@ -4896,3 +4776,131 @@ g_type_ensure (GType type)
   if (G_UNLIKELY (type == (GType)-1))
     g_error ("can't happen");
 }
+
+static void
+g_type_cleanup (void)
+{
+  GHashTableIter iter;
+  gpointer value;
+  GHashTable * vtables;
+
+  g_hash_table_iter_init (&iter, static_type_nodes_ht);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+      GType gtype = (GType) GPOINTER_TO_SIZE (value);
+      TypeNode *node;
+
+      node = lookup_type_node_I (gtype);
+      if (node->is_classed && node->data)
+        type_data_finalize (node);
+    }
+
+  g_hash_table_iter_init (&iter, static_type_nodes_ht);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+      GType gtype = (GType) GPOINTER_TO_SIZE (value);
+      TypeNode *node;
+
+      node = lookup_type_node_I (gtype);
+      if (NODE_IS_IFACE (node) && node->data)
+        type_data_finalize (node);
+    }
+
+  _g_signal_cleanup ();
+  _g_param_spec_types_cleanup ();
+  _g_object_type_cleanup ();
+  _g_param_type_cleanup ();
+  _g_value_c_cleanup ();
+
+  g_clear_pointer (&static_class_cache_funcs, g_free);
+  g_clear_pointer (&static_iface_check_funcs, g_free);
+
+  g_hash_table_iter_init (&iter, static_type_nodes_ht);
+  vtables = g_hash_table_new (NULL, NULL);
+  while (g_hash_table_iter_next (&iter, NULL, &value))
+    {
+      GType gtype = (GType) GPOINTER_TO_SIZE (value);
+      TypeNode *node;
+
+      node = lookup_type_node_I (gtype);
+
+      g_free (node->children);
+
+      if (node->is_classed)
+        {
+          IFaceEntries *entries;
+
+          entries = CLASSED_NODE_IFACES_ENTRIES_LOCKED (node);
+          if (entries)
+           {
+              guint i;
+
+             for (i = 0; i != IFACE_ENTRIES_N_ENTRIES (entries); i++)
+               g_hash_table_insert (vtables, entries->entry[i].vtable, NULL);
+            }
+
+          _g_atomic_array_free (CLASSED_NODE_IFACES_ENTRIES (node));
+
+          if (node->data != NULL)
+            g_free (node->data->class.class);
+        }
+
+      if (NODE_IS_IFACE (node))
+        {
+          IFaceHolder *iholder, *next;
+
+          _g_atomic_array_free (&node->_prot.offsets);
+
+          iholder = iface_node_get_holders_L (node);
+          while (iholder)
+            {
+              next = iholder->next;
+
+              g_free (iholder->info);
+              g_free (iholder);
+
+              iholder = next;
+            }
+
+          if (node->data != NULL)
+            g_free (node->data->iface.dflt_vtable);
+
+          g_free (iface_node_get_dependants_array_L (node));
+        }
+
+      g_free (node->data);
+
+      if (node->global_gdata != NULL)
+        g_free (node->global_gdata->qdatas);
+      g_free (node->global_gdata);
+
+      g_free (node->prerequisites);
+
+      if (G_TYPE_IS_FUNDAMENTAL (gtype))
+        node = G_STRUCT_MEMBER_P (node, -SIZEOF_FUNDAMENTAL_INFO);
+      g_free (node);
+    }
+
+  g_hash_table_foreach (vtables, (GHFunc) g_free, NULL);
+  g_hash_table_unref (vtables);
+
+  g_clear_pointer (&static_type_nodes_ht, g_hash_table_unref);
+
+  _g_atomic_array_cleanup ();
+
+  g_rw_lock_clear (&type_rw_lock);
+  g_rec_mutex_clear (&class_init_rec_mutex);
+  g_mutex_clear (&G_LOCK_NAME (type_init_lock));
+}
+
+#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA
+#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS (gtype_dtor)
+#endif
+G_DEFINE_DESTRUCTOR (gtype_dtor)
+
+static void
+gtype_dtor (void)
+{
+  if (G_UNLIKELY (g_mem_do_cleanup))
+    g_type_cleanup ();
+}
diff --git a/gobject/gvalue.c b/gobject/gvalue.c
index 95a6c8c..86c0f26 100644
--- a/gobject/gvalue.c
+++ b/gobject/gvalue.c
@@ -146,7 +146,7 @@ _g_value_c_init (void)
 }
 
 void
-g_value_c_deinit (void)
+_g_value_c_cleanup (void)
 {
   g_bsearch_array_free (transform_array, &transform_bconfig);
   transform_array = NULL;
diff --git a/gobject/tests/enums.c b/gobject/tests/enums.c
index 72df8a8..add5266 100644
--- a/gobject/tests/enums.c
+++ b/gobject/tests/enums.c
@@ -48,6 +48,8 @@ test_enum_basic (void)
   g_assert_cmpint (val->value, ==, 1);
   val = g_enum_get_value_by_nick (class, "purple");
   g_assert (val == NULL);
+
+  g_type_class_unref (class);
 }
 
 static const GFlagsValue my_flag_values[] =
@@ -110,6 +112,8 @@ test_flags_basic (void)
 
   test_flags_transform_to_string (&value);
   g_value_unset (&value);
+
+  g_type_class_unref (class);
 }
 
 int
diff --git a/gobject/tests/signals.c b/gobject/tests/signals.c
index 58c9370..b102894 100644
--- a/gobject/tests/signals.c
+++ b/gobject/tests/signals.c
@@ -762,6 +762,9 @@ test_all_types (void)
   g_assert_cmpint (all_type_handlers_count, ==, 3 + 5 + 5);
 
   g_object_unref (test);
+  g_param_spec_unref (param);
+  g_variant_unref (var);
+  g_bytes_unref (bytes);
 }
 
 static void
diff --git a/gobject/tests/threadtests.c b/gobject/tests/threadtests.c
index c14997c..c74fea4 100644
--- a/gobject/tests/threadtests.c
+++ b/gobject/tests/threadtests.c
@@ -114,12 +114,14 @@ tester_init_thread (gpointer data)
 static void
 test_threaded_class_init (void)
 {
+  GThread *t1, *t2, *t3;
+
   /* pause newly created threads */
   g_mutex_lock (&sync_mutex);
   /* create threads */
-  g_thread_create (tester_init_thread, (gpointer) my_tester0_get_type(), TRUE, NULL);
-  g_thread_create (tester_init_thread, (gpointer) my_tester1_get_type(), TRUE, NULL);
-  g_thread_create (tester_init_thread, (gpointer) my_tester2_get_type(), TRUE, NULL);
+  t1 = g_thread_create (tester_init_thread, (gpointer) my_tester0_get_type(), TRUE, NULL);
+  t2 = g_thread_create (tester_init_thread, (gpointer) my_tester1_get_type(), TRUE, NULL);
+  t3 = g_thread_create (tester_init_thread, (gpointer) my_tester2_get_type(), TRUE, NULL);
   /* execute threads */
   g_mutex_unlock (&sync_mutex);
   while (g_atomic_int_get (&mtsafe_call_counter) < (3 + 3 + 3 * 3) * NUM_COUNTER_INCREMENTS)
@@ -132,6 +134,10 @@ test_threaded_class_init (void)
     g_print ("Total initializers: %u\n", g_atomic_int_get (&mtsafe_call_counter));
   /* ensure non-corrupted counter updates */
   g_assert_cmpint (g_atomic_int_get (&mtsafe_call_counter), ==, unsafe_call_counter);
+
+  g_thread_join (t1);
+  g_thread_join (t2);
+  g_thread_join (t3);
 }
 
 typedef struct {
@@ -328,6 +334,8 @@ int
 main (int   argc,
       char *argv[])
 {
+  int ret;
+
   g_test_init (&argc, &argv, NULL);
   g_type_init ();
 
@@ -335,5 +343,13 @@ main (int   argc,
   g_test_add_func ("/GObject/threaded-object-init", test_threaded_object_init);
   g_test_add_func ("/GObject/threaded-weak-ref", test_threaded_weak_ref);
 
-  return g_test_run();
+  ret = g_test_run();
+
+  if (g_mem_do_cleanup)
+    {
+      g_mutex_clear (&sync_mutex);
+      g_cond_clear (&sync_cond);
+    }
+
+  return ret;
 }


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