mirror of
https://github.com/Ryujinx/GtkSharp.git
synced 2024-12-24 13:35:38 +00:00
Switch GLib.Object to Dispose(bool) pattern.
* glib/Object.cs: move finalization queue to ToggleRef and make Dispose() non-virtual with a protected virtual Dispose(bool). Also added a WarnOnFinalize static property to produce nags for undisposed objects. * glib/ToggleRef.cs: add finalization queue and QueueUnref method. * gtk/NodeStore.cs: override Dispose(bool) * gtk/Widget.custom: override Dispose(bool)
This commit is contained in:
parent
6be0718ff2
commit
1c980d6e71
|
@ -35,67 +35,53 @@ namespace GLib {
|
|||
ToggleRef tref;
|
||||
bool disposed = false;
|
||||
static Dictionary<IntPtr, ToggleRef> Objects = new Dictionary<IntPtr, ToggleRef>();
|
||||
static List<ToggleRef> PendingDestroys = new List<ToggleRef> ();
|
||||
static bool idle_queued;
|
||||
|
||||
~Object ()
|
||||
{
|
||||
lock (PendingDestroys) {
|
||||
lock (Objects) {
|
||||
if (Objects[Handle] is ToggleRef)
|
||||
PendingDestroys.Add (Objects [Handle]);
|
||||
Objects.Remove (Handle);
|
||||
}
|
||||
if (!idle_queued){
|
||||
Timeout.Add (50, new TimeoutHandler (PerformQueuedUnrefs));
|
||||
idle_queued = true;
|
||||
}
|
||||
}
|
||||
if (WarnOnFinalize)
|
||||
Console.Error.WriteLine ("Unexpected finalization of " + GetType() + " instance. Consider calling Dispose.");
|
||||
|
||||
Dispose (false);
|
||||
}
|
||||
|
||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void g_object_unref (IntPtr raw);
|
||||
|
||||
static bool PerformQueuedUnrefs ()
|
||||
{
|
||||
ToggleRef[] references;
|
||||
|
||||
lock (PendingDestroys){
|
||||
references = new ToggleRef [PendingDestroys.Count];
|
||||
PendingDestroys.CopyTo (references, 0);
|
||||
PendingDestroys.Clear ();
|
||||
idle_queued = false;
|
||||
}
|
||||
|
||||
foreach (ToggleRef r in references)
|
||||
r.Free ();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void Dispose ()
|
||||
public void Dispose ()
|
||||
{
|
||||
if (disposed)
|
||||
return;
|
||||
|
||||
Dispose (true);
|
||||
disposed = true;
|
||||
ToggleRef toggle_ref;
|
||||
if (Objects.TryGetValue (Handle, out toggle_ref))
|
||||
Objects.Remove (Handle);
|
||||
try {
|
||||
if (toggle_ref != null)
|
||||
toggle_ref.Free ();
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine ("Exception while disposing a " + this + " in Gtk#");
|
||||
throw e;
|
||||
}
|
||||
handle = IntPtr.Zero;
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
ToggleRef tref;
|
||||
lock (Objects) {
|
||||
if (Objects.TryGetValue (Handle, out tref)) {
|
||||
tref.QueueUnref ();
|
||||
Objects.Remove (Handle);
|
||||
}
|
||||
}
|
||||
|
||||
handle = IntPtr.Zero;
|
||||
if (tref == null)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
tref.Free ();
|
||||
else
|
||||
tref.QueueUnref ();
|
||||
}
|
||||
|
||||
public static bool WarnOnFinalize { get; set; }
|
||||
|
||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern IntPtr g_object_ref (IntPtr raw);
|
||||
|
||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void g_object_unref (IntPtr raw);
|
||||
|
||||
public static Object GetObject(IntPtr o, bool owned_ref)
|
||||
{
|
||||
if (o == IntPtr.Zero)
|
||||
|
|
|
@ -116,6 +116,37 @@ namespace GLib {
|
|||
}
|
||||
}
|
||||
|
||||
static List<ToggleRef> PendingDestroys = new List<ToggleRef> ();
|
||||
static bool idle_queued;
|
||||
|
||||
public void QueueUnref ()
|
||||
{
|
||||
lock (PendingDestroys) {
|
||||
PendingDestroys.Add (this);
|
||||
if (!idle_queued){
|
||||
Timeout.Add (50, new TimeoutHandler (PerformQueuedUnrefs));
|
||||
idle_queued = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool PerformQueuedUnrefs ()
|
||||
{
|
||||
ToggleRef[] references;
|
||||
|
||||
lock (PendingDestroys){
|
||||
references = new ToggleRef [PendingDestroys.Count];
|
||||
PendingDestroys.CopyTo (references, 0);
|
||||
PendingDestroys.Clear ();
|
||||
idle_queued = false;
|
||||
}
|
||||
|
||||
foreach (ToggleRef r in references)
|
||||
r.Free ();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void g_object_add_toggle_ref (IntPtr raw, ToggleNotifyHandler notify_cb, IntPtr data);
|
||||
|
||||
|
|
|
@ -202,13 +202,13 @@ namespace Gtk {
|
|||
#region Gtk.TreeIter handling
|
||||
ArrayList gc_handles = new ArrayList ();
|
||||
|
||||
public override void Dispose ()
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
// Free all the GCHandles pointing to the iters since they won't be garbage collected
|
||||
foreach (System.Runtime.InteropServices.GCHandle handle in gc_handles)
|
||||
handle.Free ();
|
||||
|
||||
base.Dispose ();
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
|
||||
internal void GetIter (ITreeNode node, ref TreeIter iter)
|
||||
|
|
|
@ -376,12 +376,12 @@ public void Path (out string path, out string path_reversed)
|
|||
base.CreateNativeObject (names, vals);
|
||||
}
|
||||
|
||||
public override void Dispose ()
|
||||
protected override void Dispose (bool disposing)
|
||||
{
|
||||
if (Handle == IntPtr.Zero)
|
||||
return;
|
||||
InternalDestroyed -= NativeDestroyHandler;
|
||||
base.Dispose ();
|
||||
base.Dispose (disposing);
|
||||
}
|
||||
|
||||
[DllImport ("libgobject-2.0-0.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
|
|
Loading…
Reference in a new issue