From b5e0d297bbe27cc6ee2b1a733e997c3b07732fbf Mon Sep 17 00:00:00 2001 From: Michael Hutchinson Date: Wed, 19 Sep 2012 19:41:43 -0400 Subject: [PATCH] Fix resurrection cycles in container subclasses (bxc#3801) --- gtk/Container.cs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/gtk/Container.cs b/gtk/Container.cs index 573058779..120c4c20f 100644 --- a/gtk/Container.cs +++ b/gtk/Container.cs @@ -134,9 +134,16 @@ namespace Gtk { static void ForallOld_cb (IntPtr container, bool include_internals, IntPtr cb, IntPtr data) { try { - Container obj = GLib.Object.GetObject (container, false) as Container; - CallbackInvoker invoker = new CallbackInvoker (cb, data); - obj.ForAll (include_internals, invoker); + //GtkContainer's unmanaged dispose calls forall, but by that time the managed object is gone + //so it couldn't do anything useful, and resurrecting it would cause a resurrection cycle. + //In that case, just chain to the native base in case it can do something. + Container obj = (Container) GLib.Object.TryGetObject (container); + if (obj != null) { + CallbackInvoker invoker = new CallbackInvoker (cb, data); + obj.ForAll (include_internals, invoker); + } else { + gtksharp_container_base_forall (container, include_internals, cb, data); + } } catch (Exception e) { GLib.ExceptionManager.RaiseUnhandledException (e, false); } @@ -159,9 +166,16 @@ namespace Gtk { static void Forall_cb (IntPtr container, bool include_internals, IntPtr cb, IntPtr data) { try { - Container obj = GLib.Object.GetObject (container, false) as Container; - CallbackInvoker invoker = new CallbackInvoker (cb, data); - obj.ForAll (include_internals, new Gtk.Callback (invoker.Invoke)); + //GtkContainer's unmanaged dispose calls forall, but by that time the managed object is gone + //so it couldn't do anything useful, and resurrecting it would cause a resurrection cycle. + //In that case, just chain to the native base in case it can do something. + Container obj = (Container) GLib.Object.TryGetObject (container); + if (obj != null) { + CallbackInvoker invoker = new CallbackInvoker (cb, data); + obj.ForAll (include_internals, new Gtk.Callback (invoker.Invoke)); + } else { + gtksharp_container_base_forall (container, include_internals, cb, data); + } } catch (Exception e) { GLib.ExceptionManager.RaiseUnhandledException (e, false); }