Re: Weak references for GObject
- From: Tim Janik <timj gtk org>
- To: Owen Taylor <otaylor redhat com>
- Cc: Gtk+ Developers <gtk-devel-list gnome org>, Michael Meeks <michael helixcode com>
- Subject: Re: Weak references for GObject
- Date: Sat, 30 Jun 2001 12:40:56 +0200 (CEST)
On 11 Jun 2001, Owen Taylor wrote:
> I discussed this issue for a long while wth Tim this morning;
> our concluding scheme was somewhat different than my original
> proposal.
> Tim's main concern was that people would want to create object
> types like GtkObject, with explicit destruction; every such
> object type would have:
>
> * Its own gtk_object_destroy() public function for destruction
> * Its own virtual function equivalent to ->destroy() in GtkObject
>
> This causes code duplication of tricky code portions and causes
> a lack of unity across GObject using code.
been thinking about this more and one counter concern is object types
that do not allow for explicit destruction, e.g. i got that in BSE,
there's no bse_object_destroy(), though you can connect to
BseObject::destroy which is emitted only once and guarranteed to
occour before finalize.
of course internally, i implement that through the current "last_unref"
functionality of GObject which is called ->shutdown and is currently
not externally callable. but BSE implicitely relies on ->shutdown
not being third-party callable for BseObejct derived things.
=> Hint A to not make g_object_dispose() publically callable.
> So, what Tim proposed instead was to basically move the
> destroy() virtual function into GObject and call it dispose().
we must have been on crack for the basic idea, see further down ;)
> In detail:
>
> * A dispose() virtual method would be added to the GObjectClass
> structure.
>
> * This dispose() virtual method is:
>
> - Called when someone explicitely calls g_object_dispose()
> - Called when the reference count
"...drops" you meant to add
> * Signal emission from the dispose() virtual method works.
> Resurrection will probably work too, though I don't know
> if we want to guarantee this long-term.
i guess we have to, since BSE/GTK emit signals from here and signals
need reference counting and once you got reference counting you basically
can slip-in resurrection.
> * The dispose() implementation for GtkObject does:
>
> gtk_signal_emit (object, "destroy");
> parent_class->dispose (object);
right, though with GTK_DESTROYED flag guards around the emission.
note that, unlike what we have currently, the GTK_DESTROYED guarding
flag will only prevent multiple emissions of ::destroy, it will however
_not_ ensure that ->dispose() is not called recursively on the same
object.
=> Hint B to not make g_object_dispose() a publically callable function.
furthermore, unlike 1.2, this does permit _after connections to ::destroy.
however i'm not sure we'll maintain this in the future, so it's probably
a good idea to stay destroying handlers in g_object_real_destroy(), so
people can't discover _after connection to ::destroy and rely on them ;)
> * The dispose() implementation for GObject removes all signals
> and notifies all weak references.
>
> * We remove the shutdown() virtual method in GObject since
> it is no longer needed. [1]
ok in effect i agree, though i'd rather word this as "rename
shutdown to dispose".
> So, for completely new GTK+-based code you would:
>
> * Implement what you currently do in ->destroy() in ->dispose()
we shouldn't do this, as i will explain.
> * Call g_object_dispose() instead of gtk_widget_destroy()
and also not this.
> * Use g_object_weak_ref() instead of connections to ::destroy.
> (There is no ::dispose signal) [2]
this should be fine however.
> While I think this scheme does introduce some questionable
> practices from into GObject into GTK+, one big advantage of it
s/from into GObject into GTK+/from GTK+ into GObject/
> is that the relationship between the GtkObject life-cycle
> and the GObject life-cycle is considerably simplified.
ok, now onto the main reason why simply "replacing" destroy by dispose
is not such a good idea. the very reason to introduce shutdown in the
first place was, in GTK+ core we need to do certain things when we're
about to emit ::destroy, but haven't started yet. the prime (though not
sole) example of this is gtk_widget_shutdown() removing children from
parents and (thus) unrealizing the widget.
for non-core-developers:
if we didn't (via shutdown) make sure a child is removed from its parent
before ::destroy gets emitted, widget destruction in classes derived from
GtkWidget couldn't make all kinds of assumptions like widget->window and
other resources associated with realization being gone. furthermore, since
gtk_widget_shutdown() not only removes children from their parents,
but also unrealizes toplevel widgets, X window destruction would
occour from leafs up the tree, a very slow and inefficient process.
as a result out of the remaining need for a "hook" before GtkWidget-derived
type destructors are called, and the above mentioned hints towards not making
g_object_dispose() publically callable, we should change things towards:
- not making the recommendation that people use ->dispose instead of ->destroy.
instead, for the scope of Gtk+, leave things for implementors as they are,
i.e. they shouldn't worry about dispose in their code.
- call the dispose invocation function g_object_dispose_internal(). only
library implementations should use it, e.g. for Gtk+ that'd be
gtk_object_destroy(), for BSE, that'd be nowhere (still gets triggered
upon last_unref situation), and for bonobo, where i heared explicit
destruction is required, that'd be something like bonobo_object_destroy()
i guess.
> Regards,
> Owen
>
---
ciaoTJ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]