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


James Dean Palmer <james@tiger-marmalade.com> writes:

> I'm working on an fltk (a c++ widget library) binding for guile, and
> for the most part it's going fairly smoothly, but I have a few
> questions regarding garbage collection.

You might want to look at guile-gtk which is a Guile binding to the
Gtk+ toolkit.  It should share a lot problems with your bindings, and
I think I have solved them satisfactorily.

    http://www.ping.de/sites/zagadka/guile-gtk/

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.

- Marius

[1] A `weak' link does not prevent the linked to object from becoming
    garbage.  So either the proxy could be collected while the widget
    was still alive, or the widget could go away without Scheming
    being able to prevent this.