Re: instance-private-data issue



On Tue, 2003-08-05 at 09:15, Michael Meeks wrote:
> Hi Owen,
> 
> On Sun, 2003-08-03 at 01:08, Owen Taylor wrote:
> > 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.
> 
> 	Presumably; (and this is just a stab in the dark) changing the size of
> GTypeInstance from 4 to 8 bytes (16 on 64bit machines) would also offset
> all derived GObject's fields:
> 
> struct  _GObject
> {
>   GTypeInstance g_type_instance;
> 
>   guint         ref_count;
>   GData        *qdata;
> }
> 
> 	and break binary compatibility of most gtk+ / Gnome applications ? or
> am I mis-understanding things / is this some deep future design thing ?

You probably missed the suggested hack; the extra fields go *before*
the beginning of the type-instance struct. That is, the same hack
that ORBit uses for storing CORBA_free information.

> 	From what I remember of grubbing in class_init's there was some way to
> get the true class of the type being initialized which came in some 2nd
> argument to the _class_init that most people never used; could that not
> also be used in this instance ? in combination with a
> g_type_instance_toolong_get_private_from_class (real_class, MY_TYPE_A,
> MyA); ?

Hmm, yes, you are right that the real class is passed as the second 
argument to instance_init(). This doesn't particularly help because
we're not just worried about direct calls from the instance_init()
function. A common case would be that the instance_init() function
for a derived class calls a method in the parent class that tries
to access the private data.

But maybe it's a useful component of the real solution.

> 	Or is that going to be too complex for people to remember ? I'm
> assuming randomly having not looked (sorry) that this is all part of a
> cunning plan to make people's separately allocated ->priv pointers more
> efficient by block allocating them after the object instance ?

Yes, we have that in place. It's not just a question of effiency; it's
also about being able to add private data to existing widgets.

> 	Presumably; in a singly inherited world - if you resigned yourself to 2
> allocations per object - they could be sanely blocked off into a single
> separate allocated block 

Where do you store a pointer to this separately allocated block? If you
have a place to store that, you might as well store a pointer to the
private data part of the main allocation.

> [ you could I guess even put the GData struct at the top of that, and
>  re-use that pointer ? ;-) ]

Hmm, that does provide an idea of a 4-bytes-per-GObject solution 
instead of a 8-bytes-per-GTypeInstance solution, as long as we are
willing to replace the public g_type_instance_get_private() with
g_object_get_private().

 A) Move GObject->qdata to the private data block and replace it
    with a ->priv pointer.
 B) Initialize that priv pointer using the second parameter to
    g_object_init()

> 	That would have the advantage of the offsets being invariant across
> objects of the same type, and evaluating to a constant offset for that
> type, potentially removing the need for more complexity ?

Well, with that scheme, you could potentially do:

#define MY_A_GET_PRIVATE((MyA *)((guchar *)G_OBJECT(a)->priv + private_offset_var))

and have a no-function-call solution. But that makes the interfaces
a messier.

>  - 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 didn't understand the problem B) with using __thread variables in
> glib:
> 
>  B) We can't use __thread variables in GLib, even #ifdef'ed
>     because of g_thread_init (my_vtable); They do accelerate
>     g_static_private_get() indirectly, through the chain
>     of
>        g_static_private_get => g_thread_self => g_private_get =>
>        g_private_get_posix_impl() => pthread_getspecific ()

The problem here is that someone could use the argument to g_type_init()
to replace the standard GLib threading with a user-space implementation
where __thread variables don't work properly (because it all looks
like one thread to the OS.) Such a situation is unlikely to work 
fully correctly, because GLib does depend on the C library being thread
safe, but I'm not sure we can simply declare it non-working.

Thanks for the input,
						Owen





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