static void OverrideForall(GLib.GType gtype) { if (ForallCallback == null) { ForallCallback = new ForallDelegate(Forall_cb); } gtksharp_container_override_forall(gtype.Val, ForallCallback); }
// Works around BXC #3801 - Managed Container subclasses are incorrectly resurrected, then leak. // It does this by registering an alternative callback for gtksharp_container_override_forall, which // ignores callbacks if the wrapper no longer exists. This means that the objects no longer enter a // finalized->release->dispose->re-wrap resurrection cycle. // We use a dynamic method to access internal/private GTK# API in a performant way without having to track // per-instance delegates. public static void FixContainerLeak <T> (T c) { var t = typeof(T); if (fixedContainerTypes.Add(t)) { if (forallCallback == null) { forallCallback = CreateForallCallback(); } var gt = (GLib.GType)t.GetMethod("LookupGType", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(c, null); gtksharp_container_override_forall(gt.Val, forallCallback); } }
static extern void gtksharp_container_override_forall(IntPtr gtype, ForallDelegate cb);
static void OverrideForallOld(GLib.GType gtype) { if (ForallOldCallback == null) ForallOldCallback = new ForallDelegate (ForallOld_cb); gtksharp_container_override_forall (gtype.Val, ForallOldCallback); }