Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM base/devel
FROM archlinux/archlinux:base-devel-20210627.0.27153

RUN pacman -Syy --noconfirm
RUN pacman -Syu --noconfirm
Expand Down
50 changes: 18 additions & 32 deletions Source/generator/OpaqueGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public override void Generate (GenerationInfo gen_info)
}
}

bool finalizer_needed = false;
// GtkWidgetPath has both gtk_widget_path_unref and gtk_widget_path_free
// If this happens add only one and prefer unref over free
bool disposeUnmanagedFuncAdded = false;
Comment thread
thiblahute marked this conversation as resolved.

if (unref != null) {
unref.GenerateImport (sw);
Expand All @@ -118,13 +120,18 @@ public override void Generate (GenerationInfo gen_info)
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();

sw.WriteLine ("\t\tprotected override Action<IntPtr> DisposeUnmanagedFunc {");
sw.WriteLine ("\t\t\tget {");
sw.WriteLine ("\t\t\t\treturn " + unref.CName + ";");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
disposeUnmanagedFuncAdded = true;
if (unref.IsDeprecated) {
sw.WriteLine ("\t\t[Obsolete(\"" + QualifiedName + " is now refcounted automatically\")]");
sw.WriteLine ("\t\tpublic void Unref () {}");
sw.WriteLine ();
}
finalizer_needed = true;
}

if (dispose != null) {
Expand All @@ -134,43 +141,22 @@ public override void Generate (GenerationInfo gen_info)
sw.WriteLine ("\t\t\t" + dispose.CName + " (raw);");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
if (!disposeUnmanagedFuncAdded) {
sw.WriteLine ("\t\tprotected override Action<IntPtr> DisposeUnmanagedFunc {");
sw.WriteLine ("\t\t\tget {");
sw.WriteLine ("\t\t\t\treturn " + dispose.CName + ";");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}

if (dispose.IsDeprecated) {
sw.WriteLine ("\t\t[Obsolete(\"" + QualifiedName + " is now freed automatically\")]");
sw.WriteLine ("\t\tpublic void " + dispose.Name + " () {}");
sw.WriteLine ();
}
finalizer_needed = true;
}

if (finalizer_needed) {
sw.WriteLine ("\t\tclass FinalizerInfo {");
sw.WriteLine ("\t\t\tIntPtr handle;");
sw.WriteLine ();
sw.WriteLine ("\t\t\tpublic FinalizerInfo (IntPtr handle)");
sw.WriteLine ("\t\t\t{");
sw.WriteLine ("\t\t\t\tthis.handle = handle;");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\t\tpublic bool Handler ()");
sw.WriteLine ("\t\t\t{");
if (dispose != null)
sw.WriteLine ("\t\t\t\t{0} (handle);", dispose.CName);
else if (unref != null)
sw.WriteLine ("\t\t\t\t{0} (handle);", unref.CName);
sw.WriteLine ("\t\t\t\treturn false;");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
sw.WriteLine ("\t\t~{0} ()", Name);
sw.WriteLine ("\t\t{");
sw.WriteLine ("\t\t\tif (!Owned)");
sw.WriteLine ("\t\t\t\treturn;");
sw.WriteLine ("\t\t\tFinalizerInfo info = new FinalizerInfo (Handle);");
sw.WriteLine ("\t\t\tGLib.Timeout.Add (50, new GLib.TimeoutHandler (info.Handler));");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}

#if false
Method copy = Methods ["Copy"] as Method;
Expand Down
68 changes: 66 additions & 2 deletions Source/glib/Opaque.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,78 @@ protected IntPtr Raw {
Ref (_obj);
}
}
}
}

#region IDisposable implementation
class FinalizerInfo
{
IntPtr handle;
Action<IntPtr> unrefFunc;

public FinalizerInfo (Action<IntPtr> unrefFunc, IntPtr handle)
{
this.handle = handle;
this.unrefFunc = unrefFunc;
}

public bool Handler ()
{
unrefFunc (handle);
return false;
}
}

public virtual void Dispose ()
~Opaque ()
{
Dispose (false);
}

public void Dispose ()
{
Raw = IntPtr.Zero;
Dispose (true);
GC.SuppressFinalize (this);
}

protected void Dispose (bool disposing)
{
if (Disposed)
return;
Disposed = true;
if (disposing) {
DisposeManagedResources ();
}
DisposeUnmanagedResources ();
}

/// <summary>
/// Disposes the managed resources.
/// This method is intended to be overriden.
/// </summary>
protected virtual void DisposeManagedResources ()
{
}

/// <summary>
/// Disposes the unmanaged resources.
/// This method is intended to be overriden.
/// </summary>
protected virtual void DisposeUnmanagedResources ()
{
if (!Owned || DisposeUnmanagedFunc == null)
return;
FinalizerInfo info = new FinalizerInfo (DisposeUnmanagedFunc, Handle);
Timeout.Add (50, new TimeoutHandler (info.Handler));
}

protected internal bool Disposed { get; private set; } = false;

protected virtual Action<IntPtr> DisposeUnmanagedFunc { get; }

#endregion



// These take an IntPtr arg so we don't get conflicts if we need
// to have an "[Obsolete] public void Ref ()"

Expand Down