Re: Weak references for GObject



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]