check private instance data after initialization.

Tue Aug 19 05:21:04 2003  Tim Janik  <timj@gtk.org>

        * 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.
This commit is contained in:
Tim Janik 2003-08-19 03:25:46 +00:00 committed by Tim Janik
parent 808a282944
commit 105adb9a35
3 changed files with 96 additions and 3 deletions

View File

@ -1,3 +1,13 @@
Tue Aug 19 05:21:04 2003 Tim Janik <timj@gtk.org>
* 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 <timj@gtk.org>
* gvalue.c: adapt to new gbsearcharray.h code.

View File

@ -25,6 +25,7 @@
#include "gtypeplugin.h"
#include "gvaluecollector.h"
#include "gbsearcharray.h"
#include <string.h>
@ -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'",

View File

@ -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);