summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-05-22 20:00:06 -0300
committerVitor Sousa <vitorsousa@expertisesolutions.com.br>2019-05-24 15:31:07 -0300
commit2b3b3b7704ffb311359c942824bc908cf5e1597c (patch)
tree0a901afc664fa0a229a1ba0657cbf623402547a1
parenta902b56d98710f575c27a583a59bea0840a0f85d (diff)
downloadefl-devs/vitorsousa/pin-unpin.tar.gz
csharp: Add a SafePtr wrapper in debug modedevs/vitorsousa/pin-unpin
This wrapper will trigger `ObjectDisposedException` when trying to call a method on object after it was disposed. It is enabled only with `--buildtype=debug` when configuring meson.
-rw-r--r--src/bindings/mono/eo_mono/EoWrapper.cs55
-rw-r--r--src/bindings/mono/meson.build4
-rw-r--r--src/tests/efl_mono/Eo.cs4
3 files changed, 61 insertions, 2 deletions
diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs b/src/bindings/mono/eo_mono/EoWrapper.cs
index b6ea619923..e1174a9fe8 100644
--- a/src/bindings/mono/eo_mono/EoWrapper.cs
+++ b/src/bindings/mono/eo_mono/EoWrapper.cs
@@ -9,11 +9,55 @@ namespace Efl
namespace Eo
{
+#if EFL_DEBUG
+
+public class SafeIntPtr
+{
+ private IntPtr handle;
+ private bool disposed;
+
+ private SafeIntPtr(IntPtr ptr)
+ {
+ handle = ptr;
+ }
+
+ public static implicit operator IntPtr(SafeIntPtr ptr)
+ {
+ if (ptr.disposed)
+ {
+ throw new ObjectDisposedException("Object has been disposed");
+ }
+ return ptr.handle;
+ }
+
+ public static implicit operator SafeIntPtr(IntPtr ptr)
+ {
+ return new SafeIntPtr(ptr);
+ }
+
+ public void Dispose()
+ {
+ disposed = true;
+ handle = IntPtr.Zero;
+ }
+
+ public long ToInt64()
+ {
+ return handle.ToInt64();
+ }
+}
+
+#endif
+
public abstract class EoWrapper : IWrapper, IDisposable
{
protected readonly object eventLock = new object();
protected bool inherited = false;
- protected System.IntPtr handle = IntPtr.Zero;
+#if EFL_DEBUG
+ protected SafeIntPtr handle;
+#else
+ protected IntPtr handle;
+#endif
private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback);
private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback);
@@ -91,7 +135,11 @@ public abstract class EoWrapper : IWrapper, IDisposable
if (disposing && handle != System.IntPtr.Zero)
{
IntPtr h = handle;
+#if EFL_DEBUG
+ handle.Dispose();
+#else
handle = IntPtr.Zero;
+#endif
Efl.Eo.Globals.efl_mono_native_dispose(h);
}
else
@@ -103,6 +151,9 @@ public abstract class EoWrapper : IWrapper, IDisposable
}
Monitor.Exit(Efl.All.InitLock);
+#if EFL_DEBUG
+ handle.Dispose();
+#endif
}
}
@@ -110,7 +161,7 @@ public abstract class EoWrapper : IWrapper, IDisposable
/// <returns>A string with the type and the native pointer for this object.</returns>
public override String ToString()
{
- return $"{this.GetType().Name}@[0x{(UInt64)handle:x}]";
+ return $"{this.GetType().Name}@[0x{handle.ToInt64():x}]";
}
/// <summary>Releases the underlying native instance.</summary>
diff --git a/src/bindings/mono/meson.build b/src/bindings/mono/meson.build
index 69a5f8491f..39fbde549e 100644
--- a/src/bindings/mono/meson.build
+++ b/src/bindings/mono/meson.build
@@ -148,6 +148,10 @@ if get_option('mono-beta')
extra_cs_args += '-d:EFL_BETA'
endif
+if get_option('buildtype') == 'debug'
+ extra_cs_args += '-d:EFL_DEBUG'
+endif
+
efl_mono_install_dir = join_paths(dir_lib, 'efl-mono-'+version_major)
efl_mono_xml_doc = join_paths(meson.current_build_dir(), 'efl_mono.xml')
diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs
index be66f0842c..465646d03b 100644
--- a/src/tests/efl_mono/Eo.cs
+++ b/src/tests/efl_mono/Eo.cs
@@ -522,6 +522,10 @@ class TestObjectDeletion
part.Del();
Test.AssertNull(obj.OnePart);
+
+#if EFL_DEBUG
+ Test.AssertRaises<ObjectDisposedException>(() => part.SetParent(null));
+#endif
}
}