This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Marking smobs for GC


Marius Vollmer <mvo@zagadka.ping.de> writes:

> Let me drone on a little bit.
> 
> What I found to work best is to strongly associate the smob (I like to
> call it a proxy) and the actual widget data structure.  That is, as
> long as there references to the proxy from Scheme, the widget does not
> go away.  Conversely, as long as the widget is in use by your GUI, the
> proxy does not get collected.  I think this is what you have in mind
> anyway, but it took me a few iterations to arrive at this because I
> thought I could not deal with cycles of garbage widgets without
> weakening either the link from the proxy to the widget or the link
> from the widget to the proxy[1].  But I found a way.  Here is which
> (please everybody check if it really is correct):
> 
> Gtk+ widgets are managed with a refcount.  A proxy holds a counted
> reference to their widget, while a widget has a list of SCM objects
> that need to be protected from the GC as long as the widget is alive.
> This list includes the proxy.  Widgets do not form cycles among
> themselves, so there is no problem.  Likewise, cycles formed over
> proxies are correctly handled by the Guile GC.  However, we have to be
> careful to account for cycles that half run thru proxies and half thru
> widgets.  Such a situation is not hard to achieve by having a bunch of
> widgets in the environment of event callbacks, for example.  The way I
> cope with this is to count the `internal' references to all proxied
> widgets.  A internal reference is one from another proxied widget.
> When the real refcount of the widget is higher than the number of
> internal references, its list of SCM objects is marked
> unconditionally.  When a proxy is marked, the list of SCM objects is
> marked, plus all proxies of widgets that this widget has internal
> references to.
> 
> For this to work, we need to enumerate all references from one widget
> to another.  This is hard to do in general.  For the Gtk+ bindings I
> have settled for only tracing the parent/child hierachy of the GUI.
> Missing a reference might produce a leak, tho.
> 
> Technically, I had to hook into the mark phase of the Guile GC.  I did
> this by fabricating a almost useless smob, hijacking its mark
> function, creating one object of this smob and securing this with
> scm_permanent_object.

Maybe this would be a bit easier with guardians? Doesn't require the
extra smob, at least. What you could do is create a widget guardian,
then after a gc, check for really dead widgets and chuck them out of
the guardian. At this point, though, with a working guile-gtk and all,
it's probably not worth the hassle (besides that, I haven't even
looked at the guile-gtk code, so I could just be blowing smoke,
particularly if the much of the structure to determine whether a
widget is dead or not is implemented around the marking).

I've been wondering if maybe there isn't a way for the gc to make this
sort of thing easier, but then again, if you need to do something
complicated (like mixing two different gc strategies), maybe it should
be a little involved ;). It might be possible to classify the common
problems that come up, but it's probably just as well to provide a few
examples of how to do it with currently existing facilities,
especially since we now have guardians.

-- 
Greg