link references (Re: _foreach vs _forall ...)

On 5 Sep 1998, Marius Vollmer wrote:

> Tim Janik <> writes:
> > i've continued to work on this (got distracted by some personall issues),
> > and the result is this:
> Hi,
> errm, can I take this opportunity to introduce the `reference tracing'
> feature I want to have?

hm, i wasn't really aware of you wanting to have that implemented,
did you mention that earlier and i missed it?

> Basically, I want to have a way to enumerate absolutely all GtkObjects
> that are referenced by a certain other GtkObject, that is all
> GtkObjects that the other GtkObject has called gtk_object_ref for.
> This is very useful for language bindings that have a tracing garbage
> collector (like Guile).  With this reference tracing function, the
> garbage collector can detect cycles of unused objects.

hm, do you really encounter such behaviour in gtk?
i know such references are possible, but does gtk really introduce them?

> Tracing the references is close to enumerating all children (including
> the internals), but it should include still more references, like from
> a Tooltips object to the widgets that it has tips for (iff tooltips
> have such references). 
> I think the INCLUDE_INTERNALS argument of the forall method could be
> extended to be a enum with members GTK_INCLUDE_USER,
> GTK_INCLUDE_INTERNAL, GTK_INCLUDE_REFS or something.  It is ok to miss
> some of these references, so treating GTK_INCLUDE_REFS as identical to
> GTK_INCLUDE_INTERNAL would be allowed, if that makes the conversion
> more convenient.
> The problem is that this reference tracing is not restricted to
> containers, so the forall method would have to be added to GtkObject
> instead.

i think we should keep _forall() as an iterator for gtkcontainer that
will walk a container's children list, as it is actually part of the
parent<->child relationship concept which is only available for widgets.
also, you wouldn't get the desired effect by using GtkContainer::forall,
because we keep the reference count for parent<->child relations on
the children, not on the parents. so rather than having the children
presented through the parents _forall method, you'd have the parents
presented in the children's _forall methods.

> What do you think?  Can forall take the additional burden or should I
> go for a different class method all together?

we need a different approach for GtkObject based reference tracing, and
i don't even think we need a class method at all.
for the implementation side, i'd suggest something like (function names
are arguable as always, maybe you find better ones):

void    gtk_object_link_ref    (GtkObject *object,
                                GtkObject *link_owner);
void    gtk_object_link_unref  (GtkObject *object,
                                GtkObject *link_owner);
GSList* gtk_object_link_refs   (GtkObject *object);

so gtk_object_link_ref() will increase the reference of `link_owner' on behalf
of `object', and thus `object' will get added to `link_owner's link_refs list.
gtk_object_link_unref() will revert that.
gtk_object_link_refs() returns a linked list of object pointers that hold
references to `object' (it returns !=NULL for objects that have been passed to
gtk_object_link_ref() as `link_owner').
the link_refs list should actually be stored through the keyed data mechanism of
objects, just like we do it with signal handlers currently.

so far for the suggestion. marius, can you extend on the use of these link
references? afaik, the only advantage it gives you is that you can detect
circular references on objects and in such cases forcefully destroy one of
them. but that would only hold for:

(object1->ref_count == 1 && object1->link_refs == object2 &&
 object2->ref_count == 1 && object2->link_refs == object1)

which is pretty rare as a case, no?

since the above suggested changes will make referencing/unreferencing between
objects considerably more expesive, i'd like to see the basic concept
reasonably justified, before starting out to change all the referencing code
out there.


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