[glib/wip/free: 3/6] get gobject working, except for dynamic types
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/free: 3/6] get gobject working, except for dynamic types
- Date: Thu, 31 Oct 2013 15:33:51 +0000 (UTC)
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]