diff options
author | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2019-05-22 20:00:06 -0300 |
---|---|---|
committer | Vitor Sousa <vitorsousa@expertisesolutions.com.br> | 2019-05-24 15:31:07 -0300 |
commit | 2b3b3b7704ffb311359c942824bc908cf5e1597c (patch) | |
tree | 0a901afc664fa0a229a1ba0657cbf623402547a1 | |
parent | a902b56d98710f575c27a583a59bea0840a0f85d (diff) | |
download | efl-2b3b3b7704ffb311359c942824bc908cf5e1597c.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.cs | 55 | ||||
-rw-r--r-- | src/bindings/mono/meson.build | 4 | ||||
-rw-r--r-- | src/tests/efl_mono/Eo.cs | 4 |
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 } } |