[Gtk-sharp-list] refcounting, GC, and glade.. (patch, need review)

Mike Kestner mkestner@ximian.com
14 Oct 2002 11:01:41 -0500

On Sun, 2002-10-13 at 18:04, Vladimir Vukicevic wrote:

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

This will only ensure that the vast majority of GObject refs get leaked,
because we own most of the refs that are returned by methods. What we
need is a deterministic way to identify owned and unowned refs from the
gtk API, which doesn't currently exist.  

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

No, it's not tricky to get right, and it's what we already do.  In the
Raw property set code, we insert a hashtable entry to track existing
wrappers.  In GetObject, we return the wrapper object for a given handle
if it's in the hash, otherwise we wrap it, which eventually calls the
GLib.Object(IntPtr) ctor, which sets Raw, which inserts it in the hash,

The cause of all these problems seems to be that we are getting object
refs from "some" gtk methods which we don't own.  We can't blindly ref
these, because we do own most of the refs, and to ref them again will
just cause them to be leaked.

There is already a bug report to rework the static object hash to store
WeakRefs so that the hashtable won't cause C# objects to be ignored by
the GC.

> - For Gtk.Object derivatives:
>   - We need to ref and sink the objects in the constructors.  Right now
> he floating object behaviour is fairly broken;

How?  We already do handle the sunken object case using glue and an
overridden dispose handler.

> 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 ();

This is easily accomplished via the Gtk.Object(IntPtr) ctor, if needed.
However, I think the existing Dispose solution is fine. Perhaps the glue
function should sink instead of unref, though, to avoid the harmless,
but ugly, warning.

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

Woah.  Who says that we don't own every ref returned by a get method? If
that's true, then maybe that helps, but I doubt that is true.  The real
issue is that the Gtk api is inconsistent in its ref ownership semantics
and we need to overcome this with a solution that identifies unowned
references so that we can ref only those.  

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

Based on what I've read so far in this mail, I think the only likely
result will be the leaking of refs, which we can accomplish by removing
the Dispose functionality until we can solve the ref ownership
identification issue.

Mike Kestner <mkestner@ximian.com>