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] |
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.