class referencing and type implementation mutations (Re: Audit module)



On 16 Jun 2001, Owen Taylor wrote:

> 
> Havoc Pennington <hp redhat com> writes:
> 
> > This raises a GObject API issue, which is the need for the class_ref
> > on GtkWidgetClass - should GtkWidget get unloaded after get_type()? I
> > found that very surprising. And I found it pretty weird when
> > g_signal_lookup() silently returned 0 in this case.
> 
> I don't think this is a question of it being loaded - I think
> it is never getting loaded at all.
> 
> IMO, g_signal_lookup() should do a g_type_class_ref()/unref() around
> the lookup.

while that might sound like an easy solution, it isn't.
for dynamic classes, g_signal_lookup() would return an invalid ID,
since the class is unref-ed in that function again, and therefore
upon function exit, its signals got destroyed.

you might think that this is not _that_ bad, since there's not much
you could do with a signal id without having an instance, except
for, say, g_signal_query().
but with g_signal_query() the problem really emerges, the filled
in query structure points to fields in a signal node, if
g_signal_query() basically did (pseudo-pseudo-code ;)
  { class_ref(); tmp = class->signal->name; class_unref(); return tmp; }
the returned value is obviously invalid.

for that reason (similar for the enum functions), the GSignal
functions don't ref classes.

the docs just need to properly reflect this behaviour.

as an aside, even if g_signal_query() and friends copyied everything
they returned, i still couldn't make the guarrantee that IDs remain
the same across class re-initializations, and also queries could become
extremely expensive, consider code ala:

+++GSignal API boundary
class_ref();
n = class->n_signals;
class_unref();
---GSignal API boundary

for (i = 0; i < n; i++)
{
  char *str;
  
  +++GSignal API boundary
  class_ref();
  str = g_strdup (class->signals[i]->name);
  class_unref();
  ---GSignal API boundary

  printf ("signal: %s\n", str);
  g_free (str);
}

remember, class_ref/class_unref might involve module loading,
and the above is basically what would happen if all enum/signal
functions blindly ref-ed classes.

furthermore, the above code would simply be incorrect, because GType
modules are not obligued to stay binary compatible or
introspectably constant across reloads, which makes complete
sense if they are accessed only via generic APIs (say, only
by using functions of a base type of the class being loaded,
e.g. GObject). so in the above example, 'n' might validly be
different after a reload.

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ





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