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)
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
9namespace Eo 9namespace Eo
10{ 10{
11 11
12#if EFL_DEBUG
13
14public class SafeIntPtr
15{
16 private IntPtr handle;
17 private bool disposed;
18
19 private SafeIntPtr(IntPtr ptr)
20 {
21 handle = ptr;
22 }
23
24 public static implicit operator IntPtr(SafeIntPtr ptr)
25 {
26 if (ptr.disposed)
27 {
28 throw new ObjectDisposedException("Object has been disposed");
29 }
30 return ptr.handle;
31 }
32
33 public static implicit operator SafeIntPtr(IntPtr ptr)
34 {
35 return new SafeIntPtr(ptr);
36 }
37
38 public void Dispose()
39 {
40 disposed = true;
41 handle = IntPtr.Zero;
42 }
43
44 public long ToInt64()
45 {
46 return handle.ToInt64();
47 }
48}
49
50#endif
51
12public abstract class EoWrapper : IWrapper, IDisposable 52public abstract class EoWrapper : IWrapper, IDisposable
13{ 53{
14 protected readonly object eventLock = new object(); 54 protected readonly object eventLock = new object();
15 protected bool inherited = false; 55 protected bool inherited = false;
16 protected System.IntPtr handle = IntPtr.Zero; 56#if EFL_DEBUG
57 protected SafeIntPtr handle;
58#else
59 protected IntPtr handle;
60#endif
17 61
18 private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback); 62 private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback);
19 private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback); 63 private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback);
@@ -91,7 +135,11 @@ public abstract class EoWrapper : IWrapper, IDisposable
91 if (disposing && handle != System.IntPtr.Zero) 135 if (disposing && handle != System.IntPtr.Zero)
92 { 136 {
93 IntPtr h = handle; 137 IntPtr h = handle;
138#if EFL_DEBUG
139 handle.Dispose();
140#else
94 handle = IntPtr.Zero; 141 handle = IntPtr.Zero;
142#endif
95 Efl.Eo.Globals.efl_mono_native_dispose(h); 143 Efl.Eo.Globals.efl_mono_native_dispose(h);
96 } 144 }
97 else 145 else
@@ -103,6 +151,9 @@ public abstract class EoWrapper : IWrapper, IDisposable
103 } 151 }
104 152
105 Monitor.Exit(Efl.All.InitLock); 153 Monitor.Exit(Efl.All.InitLock);
154#if EFL_DEBUG
155 handle.Dispose();
156#endif
106 } 157 }
107 } 158 }
108 159
@@ -110,7 +161,7 @@ public abstract class EoWrapper : IWrapper, IDisposable
110 /// <returns>A string with the type and the native pointer for this object.</returns> 161 /// <returns>A string with the type and the native pointer for this object.</returns>
111 public override String ToString() 162 public override String ToString()
112 { 163 {
113 return $"{this.GetType().Name}@[0x{(UInt64)handle:x}]"; 164 return $"{this.GetType().Name}@[0x{handle.ToInt64():x}]";
114 } 165 }
115 166
116 /// <summary>Releases the underlying native instance.</summary> 167 /// <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')
148 extra_cs_args += '-d:EFL_BETA' 148 extra_cs_args += '-d:EFL_BETA'
149endif 149endif
150 150
151if get_option('buildtype') == 'debug'
152 extra_cs_args += '-d:EFL_DEBUG'
153endif
154
151efl_mono_install_dir = join_paths(dir_lib, 'efl-mono-'+version_major) 155efl_mono_install_dir = join_paths(dir_lib, 'efl-mono-'+version_major)
152efl_mono_xml_doc = join_paths(meson.current_build_dir(), 'efl_mono.xml') 156efl_mono_xml_doc = join_paths(meson.current_build_dir(), 'efl_mono.xml')
153 157
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
522 part.Del(); 522 part.Del();
523 523
524 Test.AssertNull(obj.OnePart); 524 Test.AssertNull(obj.OnePart);
525
526#if EFL_DEBUG
527 Test.AssertRaises<ObjectDisposedException>(() => part.SetParent(null));
528#endif
525 } 529 }
526} 530}
527 531