diff --git a/ChangeLog b/ChangeLog index 2869daa33..6a12415f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-05-08 Joe Shaw + + * glib/ValueArray.cs: Don't immediately free ValueArrays; queue + them up to be freed in the main thread by using a Timeout. This + fixes SMP deadlocks when the GValues contained therein aren't + threadsafe (like GDK resources). Fixes Novell bug #168650. + 2006-05-04 Peter Johanson * gtk/glue/cellrenderer.c: Revert r59683, as it causes issues for diff --git a/glib/ValueArray.cs b/glib/ValueArray.cs index 1d4f79057..d0ee748c2 100644 --- a/glib/ValueArray.cs +++ b/glib/ValueArray.cs @@ -29,6 +29,9 @@ namespace GLib { private IntPtr handle = IntPtr.Zero; + static private ArrayList PendingFrees = new ArrayList (); + static private bool idle_queued = false; + [DllImport("libgobject-2.0-0.dll")] static extern IntPtr g_value_array_new (uint n_preallocs); @@ -62,9 +65,35 @@ namespace GLib { if (Handle == IntPtr.Zero) return; - g_value_array_free (Handle); + lock (PendingFrees) { + PendingFrees.Add (handle); + + if (! idle_queued) { + Timeout.Add (50, new TimeoutHandler (PerformFrees)); + idle_queued = true; + } + } + handle = IntPtr.Zero; } + + static bool PerformFrees () + { + IntPtr[] handles; + + lock (PendingFrees) { + idle_queued = false; + + handles = new IntPtr [PendingFrees.Count]; + PendingFrees.CopyTo (handles, 0); + PendingFrees.Clear (); + } + + foreach (IntPtr h in handles) + g_value_array_free (h); + + return false; + } public IntPtr Handle { get {