instance-private-data issue



So, say you have classes MyA, MyB, MyB deriving from MyA. And
you have an instance init function for My:

static void
my_a_init (MyA *a)
{
  MyAPrivate *priv =  G_TYPE_INSTANCE_GET_PRIVATE (a,
                                                   MY_TYPE_A,
                                                   MyA);

  /* use priv */

}

All fine, right? Well, actually no. The problem is that 
g_type_instance_get_private() looks at:

 a->g_class->g_type

to find out the type of a, and thus the offset to the private
data. Well, the way GObject works, a->g_class->g_type is
always MY_TYPE_A in my_a_instance_init(), even when we are
really initializing a MY_TYPE_B.


===
   for (i = node->n_supers; i > 0; i--)
    {
      TypeNode *pnode;
                                                                                                                                          
      pnode = lookup_type_node_I (node->supers[i]);
      if (pnode->data->instance.instance_init)
        {
=>        instance->g_class = pnode->data->instance.class;
          pnode->data->instance.instance_init (instance, class);
        }
    }
===

For those not in the know, the reason it works like this is that
the idea is to avoid ever accessing the virtual functions for
MyB until the instance_init for MyB is called. [*]

So, how do we fix the problem? Two ideas I can come up with:

 - increase GTypeInstance from 4 bytes to 8 bytes (on
   32 bits), caching the real type *before* the public g_class field.

 - Use thread-private data to keep track of a stack of
   currently-being-initialized objects with their real types, and 
   have g_type_instance_get_private() check that.

I don't think not fixing the issue is an option; you could easily
have MyA < MyB < MyC situation where my_b_init() calls a function
in MyA that tries to access IPD.

Regards,
						Owen

[*] This is sort of screwy; while calling vfuncs on a partially
initially object is undesirable, calling overridden vfuncs is even
more so. But it isn't something we can change
after 5 years.





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