Re: instance-private-data issue
- From: Owen Taylor <otaylor redhat com>
- To: Michael Meeks <michael ximian com>
- Cc: Gtk Hackers <gtk-devel-list gnome org>, Tim Janik <timj gtk org>
- Subject: Re: instance-private-data issue
- Date: 05 Aug 2003 09:58:23 -0400
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]