[Gtk-sharp-list] refcounting, GC, and glade.. (patch, need
review)
Vladimir Vukicevic
vladimir@pobox.com
13 Oct 2002 16:04:03 -0700
Hmm. I just had a discussion with owen where he gave me a crash-course
in glib/gtk memory management. It looks to me we're doing a few things
wrong. Currently, every gobject that we get back we unref() when it's
finalized in C#. This I'm pretty sure is the wrong behaviour. From
talking to him, it looks like the following needs to happen:
- We need to either:
- Ref every object we get back, and create a separate C# wrapper every
time, even if the underlying Handle will be the same. This seems the
easiest and least error-prone thing to do.
- Ref only the first time we see a particular object pointer, and
store the C# object - return the same c# object for the same glib
object. This would be doable, but tricky to get right -- by storing
those objects in the hashtable, they'll never get c# finalized, hence
never gobject unref'd.
- For Gtk.Object derivatives:
- We need to ref and sink the objects in the constructors. Right now
he floating object behaviour is fairly broken; it's only not causing too
many problems for small things because every widget that gets added to a
container is sunk by that container -- this also means that we never own
the reference to this widget in c#, and the underlying handle could
become invalid at any time. Small code snippet that shows this problem:
public class Driver {
public static void Main () {
Gtk.Application.Init ();
using (Gtk.Widget w = new Gtk.Label ("foo")) {
}
}
}
This will spam a warning to stderr about finalizing a floating object,
since noone has officially taken ownership of this object.
The only solution to the sinking problem that I can think of is to
modify the generator so that it does the right thing in every object's
constructors that are a derivative of Gtk.Object -- namely,
Raw = gtk_foo_new (...)
Ref ();
Sink ();
instead of just assigning to Raw as they do now. All objects that are
returned by get_* or whatever functions should come unreffed -- in this
case we need to Ref() and create a C# wrapper.
I think this should get us most of the way towards correct object
management; I'm going to try implementing this tonight and see where I
end up.
- Vlad
--
Vladimir Vukicevic <vladimir@pobox.com>