From 105adb9a35c7a4976c0b9c45bdcbf3f25a2ee184 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Tue, 19 Aug 2003 03:25:46 +0000 Subject: [PATCH] check private instance data after initialization. Tue Aug 19 05:21:04 2003 Tim Janik * testgobject.c (main): check private instance data after initialization. * gtype.c: for instances with private data, store the real class pointer in a bsearch array during class initialization. (g_type_instance_get_private): fetch the real class of an instance from the bsearch array if necessary. --- gobject/ChangeLog | 10 +++++++ gobject/gtype.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++-- gobject/testgobject.c | 6 ++++ 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/gobject/ChangeLog b/gobject/ChangeLog index dbf542b..2e37f1d 100644 --- a/gobject/ChangeLog +++ b/gobject/ChangeLog @@ -1,3 +1,13 @@ +Tue Aug 19 05:21:04 2003 Tim Janik + + * testgobject.c (main): check private instance data after + initialization. + + * gtype.c: for instances with private data, store the real class + pointer in a bsearch array during class initialization. + (g_type_instance_get_private): fetch the real class of + an instance from the bsearch array if necessary. + Tue Aug 19 04:08:14 2003 Tim Janik * gvalue.c: adapt to new gbsearcharray.h code. diff --git a/gobject/gtype.c b/gobject/gtype.c index 891053b..faf4481 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -25,6 +25,7 @@ #include "gtypeplugin.h" #include "gvaluecollector.h" +#include "gbsearcharray.h" #include @@ -1374,6 +1375,68 @@ type_total_instance_size_I (TypeNode *node) } /* --- type structure creation/destruction --- */ +typedef struct { + gpointer instance; + gpointer class; +} InstanceRealClass; +static gint +instance_real_class_cmp (gconstpointer p1, + gconstpointer p2) +{ + const InstanceRealClass *irc1 = p1; + const InstanceRealClass *irc2 = p2; + guint8 *i1 = irc1->instance; + guint8 *i2 = irc2->instance; + return G_BSEARCH_ARRAY_CMP (i1, i2); +} +G_LOCK_DEFINE_STATIC (instance_real_class); +static GBSearchArray *instance_real_class_bsa = NULL; +static GBSearchConfig instance_real_class_bconfig = { + sizeof (InstanceRealClass), + instance_real_class_cmp, + 0, +}; +static inline void +instance_real_class_set (gpointer instance, + GTypeClass *class) +{ + InstanceRealClass key; + key.instance = instance; + key.class = class; + G_LOCK (instance_real_class); + if (!instance_real_class_bsa) + instance_real_class_bsa = g_bsearch_array_create (&instance_real_class_bconfig); + instance_real_class_bsa = g_bsearch_array_replace (instance_real_class_bsa, &instance_real_class_bconfig, &key); + G_UNLOCK (instance_real_class); +} +static inline void +instance_real_class_remove (gpointer instance) +{ + InstanceRealClass key, *node; + guint index; + key.instance = instance; + G_LOCK (instance_real_class); + node = g_bsearch_array_lookup (instance_real_class_bsa, &instance_real_class_bconfig, &key); + index = g_bsearch_array_get_index (instance_real_class_bsa, &instance_real_class_bconfig, node); + instance_real_class_bsa = g_bsearch_array_remove (instance_real_class_bsa, &instance_real_class_bconfig, index); + if (!g_bsearch_array_get_n_nodes (instance_real_class_bsa)) + { + g_bsearch_array_free (instance_real_class_bsa, &instance_real_class_bconfig); + instance_real_class_bsa = NULL; + } + G_UNLOCK (instance_real_class); +} +static inline GTypeClass* +instance_real_class_get (gpointer instance) +{ + InstanceRealClass key, *node; + key.instance = instance; + G_LOCK (instance_real_class); + node = g_bsearch_array_lookup (instance_real_class_bsa, &instance_real_class_bconfig, &key); + G_UNLOCK (instance_real_class); + return node ? node->class : NULL; +} + GTypeInstance* g_type_create_instance (GType type) { @@ -1428,6 +1491,9 @@ g_type_create_instance (GType type) } else instance = g_malloc0 (total_instance_size); /* fine without read lock */ + + if (node->data->instance.private_size) + instance_real_class_set (instance, class); for (i = node->n_supers; i > 0; i--) { TypeNode *pnode; @@ -1439,8 +1505,10 @@ g_type_create_instance (GType type) pnode->data->instance.instance_init (instance, class); } } + if (node->data->instance.private_size) + instance_real_class_remove (instance); + instance->g_class = class; - if (node->data->instance.instance_init) node->data->instance.instance_init (instance, class); @@ -3119,11 +3187,20 @@ g_type_instance_get_private (GTypeInstance *instance, TypeNode *instance_node; TypeNode *private_node; TypeNode *parent_node; + GTypeClass *class; gsize offset; g_return_val_if_fail (instance != NULL && instance->g_class != NULL, NULL); - - instance_node = lookup_type_node_I (instance->g_class->g_type); + + /* while instances are initialized, their class pointers change, + * so figure the instances real class first + */ + if (instance_real_class_bsa) + class = instance_real_class_get (instance); + else + class = instance->g_class; + + instance_node = lookup_type_node_I (class->g_type); if (G_UNLIKELY (!instance_node || !instance_node->is_instantiatable)) { g_warning ("instance of invalid non-instantiatable type `%s'", diff --git a/gobject/testgobject.c b/gobject/testgobject.c index 7ea341e..6f7832a 100644 --- a/gobject/testgobject.c +++ b/gobject/testgobject.c @@ -222,6 +222,7 @@ test_object_check_private_init (TestObject *tobject) priv = TEST_OBJECT_GET_PRIVATE (tobject); + g_print ("private data during initialization: %u == %u\n", priv->dummy1, 54321); g_assert (priv->dummy1 == 54321); } static gboolean @@ -379,6 +380,7 @@ main (int argc, GType type; TestObject *sigarg; DerivedObject *dobject; + TestObjectPrivate *priv; gchar *string = NULL; g_log_set_always_fatal (g_log_set_always_fatal (G_LOG_FATAL_MASK) | @@ -412,6 +414,10 @@ main (int argc, g_print ("MAIN: call iface print-string on test and derived object:\n"); iface_print_string (TEST_IFACE (sigarg), "iface-string-from-test-type"); iface_print_string (TEST_IFACE (dobject), "iface-string-from-derived-type"); + + priv = TEST_OBJECT_GET_PRIVATE (dobject); + g_print ("private data after initialization: %u == %u\n", priv->dummy1, 54321); + g_assert (priv->dummy1 == 54321); g_object_unref (sigarg); g_object_unref (dobject); -- 2.7.4