summaryrefslogtreecommitdiff
path: root/src/bindings
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-07-01 15:35:35 -0300
committerJaehyun-Cho <35288529+Jaehyun-Cho@users.noreply.github.com>2019-07-05 09:57:23 +0900
commit00a1a203a5d6825460d83bd32ae43f8d88ec8d3f (patch)
tree662698bbe25b713792c178a6bc34ac4cf43aa432 /src/bindings
parent73df0d47ff914211ee0a0b5fe46a381f1cd30f10 (diff)
csharp: Fix Future callback lifetime
Assigning a method directly to a field expecting a delegate creates a delegate on the fly. This delegate can be collected normally as any collectable object. In dotnet the GC is more aggressive, causing this delegate to be collected and C trying to call an invalid function. To avoid this, we create a static delegate that will be passed to C. Its lifetime will be tied to the static method it wraps.
Diffstat (limited to 'src/bindings')
-rw-r--r--src/bindings/mono/eina_mono/eina_promises.cs6
1 files changed, 4 insertions, 2 deletions
diff --git a/src/bindings/mono/eina_mono/eina_promises.cs b/src/bindings/mono/eina_mono/eina_promises.cs
index 34561a5b08..dc8642aeaa 100644
--- a/src/bindings/mono/eina_mono/eina_promises.cs
+++ b/src/bindings/mono/eina_mono/eina_promises.cs
@@ -295,12 +295,14 @@ public class Future
295 private static IntPtr ThenRaw(IntPtr previous, ResolvedCb cb) 295 private static IntPtr ThenRaw(IntPtr previous, ResolvedCb cb)
296 { 296 {
297 FutureDesc desc = new FutureDesc(); 297 FutureDesc desc = new FutureDesc();
298 desc.cb = NativeResolvedCb; 298 desc.cb = NativeResolvedCbDelegate;
299 GCHandle handle = GCHandle.Alloc(cb); 299 GCHandle handle = GCHandle.Alloc(cb);
300 desc.data = GCHandle.ToIntPtr(handle); 300 desc.data = GCHandle.ToIntPtr(handle);
301 return eina_future_then_from_desc(previous, desc); 301 return eina_future_then_from_desc(previous, desc);
302 } 302 }
303 303
304 private static FutureCb NativeResolvedCbDelegate = new FutureCb(NativeResolvedCb);
305
304 private static Eina.ValueNative NativeResolvedCb(IntPtr data, Eina.ValueNative value, IntPtr dead_future) 306 private static Eina.ValueNative NativeResolvedCb(IntPtr data, Eina.ValueNative value, IntPtr dead_future)
305 { 307 {
306 GCHandle handle = GCHandle.FromIntPtr(data); 308 GCHandle handle = GCHandle.FromIntPtr(data);
@@ -340,7 +342,7 @@ public class Future
340 for (; i < cbsList.Count(); i++) 342 for (; i < cbsList.Count(); i++)
341 { 343 {
342 ResolvedCb cb = cbsList[i]; 344 ResolvedCb cb = cbsList[i];
343 descs[i].cb = NativeResolvedCb; 345 descs[i].cb = NativeResolvedCbDelegate;
344 GCHandle handle = GCHandle.Alloc(cb); 346 GCHandle handle = GCHandle.Alloc(cb);
345 descs[i].data = GCHandle.ToIntPtr(handle); 347 descs[i].data = GCHandle.ToIntPtr(handle);
346 } 348 }