Attempt minimal changes to obtain proper disposing.

This commit is contained in:
Mads Kruse Johnsen 2019-06-03 18:17:32 +02:00 committed by cra0zy
parent 32fdca5754
commit 2e1882d31e
5 changed files with 74 additions and 57 deletions

View file

@ -21,55 +21,10 @@
namespace GLib {
using System;
using System.Runtime.InteropServices;
public class InitiallyUnowned : Object {
protected InitiallyUnowned (IntPtr raw) : base (raw) {}
public new static GLib.GType GType {
get {
return GType.Object;
}
}
delegate void d_g_object_ref_sink(IntPtr raw);
static d_g_object_ref_sink g_object_ref_sink = FuncLoader.LoadFunction<d_g_object_ref_sink>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_ref_sink"));
protected override IntPtr Raw {
get {
return base.Raw;
}
set {
if (value != IntPtr.Zero)
g_object_ref_sink (value);
base.Raw = value;
}
}
delegate bool d_g_object_is_floating(IntPtr raw);
static d_g_object_is_floating g_object_is_floating = FuncLoader.LoadFunction<d_g_object_is_floating>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_is_floating"));
delegate void d_g_object_force_floating(IntPtr raw);
static d_g_object_force_floating g_object_force_floating = FuncLoader.LoadFunction<d_g_object_force_floating>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_force_floating"));
delegate void d_g_object_unref(IntPtr raw);
static d_g_object_unref g_object_unref = FuncLoader.LoadFunction<d_g_object_unref>(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_unref"));
public bool IsFloating {
get {
return g_object_is_floating (Handle);
}
set {
if (value == true) {
if (!IsFloating)
g_object_force_floating (Handle);
} else {
g_object_ref_sink (Handle);
g_object_unref (Handle);
}
}
}
}
}

View file

@ -28,9 +28,11 @@ namespace GLib {
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Linq;
public class Object : IWrapper, IDisposable {
protected internal bool owned;
IntPtr handle;
ToggleRef tref;
bool disposed = false;
@ -38,6 +40,50 @@ namespace GLib {
static Dictionary<IntPtr, ToggleRef> Objects = new Dictionary<IntPtr, ToggleRef>();
static Dictionary<IntPtr, Dictionary<IntPtr, GLib.Value>> PropertiesToSet = new Dictionary<IntPtr, Dictionary<IntPtr, GLib.Value>>();
static readonly List<long> IgnoreAddresses = new List<long> ();
static readonly Dictionary<long, string> ConstructionTraces = new Dictionary<long, string> ();
public static void PrintHeldObjects ()
{
Console.WriteLine ($"---- BEGIN HELD OBJECTS ({Objects.Count - IgnoreAddresses.Count}) [Total: {Objects.Count}]----:");
lock (Objects)
{
foreach (var obj in Objects)
{
if (IgnoreAddresses.Contains (obj.Key.ToInt64 ()))
continue;
Console.WriteLine (obj.Key.ToInt64 () + " -> " + obj.Value.Target.GetType ());
if (ConstructionTraces.ContainsKey (obj.Key.ToInt64 ()))
Console.WriteLine (" AT: " + ConstructionTraces[obj.Key.ToInt64 ()].Split (Environment.NewLine.ToCharArray ()).FirstOrDefault (x => x.Contains ("OpenMedicus"))); //Aggregate((x,y) => x + Environment.NewLine + y)
}
}
Console.WriteLine ($"---- END HELD OBJECTS ({Objects.Count - IgnoreAddresses.Count}) [Total: {Objects.Count}]----:");
}
public static void SetIgnore ()
{
IgnoreAddresses.Clear ();
lock (Objects)
{
foreach (var address in Objects)
IgnoreAddresses.Add (address.Key.ToInt64 ());
}
}
static bool traceConstruction = true;
public bool TraceConstruction
{
get => traceConstruction;
set
{
ConstructionTraces.Clear ();
traceConstruction = value;
}
}
~Object ()
{
if (WarnOnFinalize)
@ -65,6 +111,7 @@ namespace GLib {
}
}
// Console.WriteLine ("Disposed " + GetType() + " " + RefCount);
handle = IntPtr.Zero;
if (tref == null)
return;
@ -85,6 +132,16 @@ namespace GLib {
signals = null;
}
public void FreeSignals ()
{
if (signals != null) {
var copy = signals.Values;
signals = null;
foreach (Signal s in copy)
s.Free ();
}
}
public static bool WarnOnFinalize { get; set; }
delegate IntPtr d_g_object_ref(IntPtr raw);
@ -133,9 +190,6 @@ namespace GLib {
return obj;
}
if (!owned_ref)
g_object_ref (o);
obj = GLib.ObjectManager.CreateObject(o);
if (obj == null) {
g_object_unref (o);

View file

@ -38,6 +38,7 @@ namespace GLib {
gch = GCHandle.Alloc (this);
reference = target;
g_object_add_toggle_ref (target.Handle, ToggleNotifyCallback, (IntPtr) gch);
if (target.owned && !(target is InitiallyUnowned))
g_object_unref (target.Handle);
}
@ -67,6 +68,8 @@ namespace GLib {
void Free ()
{
Target?.FreeSignals ();
if (hardened)
g_object_unref (handle);
else

View file

@ -391,7 +391,12 @@ namespace Gtk {
{
if (Handle == IntPtr.Zero)
return;
if (disposing)
gtk_widget_destroy (Handle);
InternalDestroyed -= NativeDestroyHandler;
base.Dispose (disposing);
}
@ -409,12 +414,9 @@ namespace Gtk {
delegate void d_gtk_widget_destroy(IntPtr raw);
static d_gtk_widget_destroy gtk_widget_destroy = FuncLoader.LoadFunction<d_gtk_widget_destroy>(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_widget_destroy"));
[Obsolete("Use Dispose")]
public virtual void Destroy ()
{
if (Handle == IntPtr.Zero)
return;
gtk_widget_destroy (Handle);
InternalDestroyed -= NativeDestroyHandler;
}
}
}

View file

@ -149,6 +149,9 @@ namespace GtkSharp.Generation {
}
Body.Initialize(gen_info, false, false, "");
if (container_type is ObjectGen) {
sw.WriteLine ("\t\t\towned = true;");
}
sw.WriteLine("\t\t\t{0} = {1}({2});", container_type.AssignToName, CName, Body.GetCallString (false));
Body.Finish (sw, "");
Body.HandleException (sw, "");