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.
This commit is contained in:
Lauro Moura 2019-07-01 15:35:35 -03:00 committed by Jaehyun-Cho
parent 73df0d47ff
commit 00a1a203a5
1 changed files with 4 additions and 2 deletions

View File

@ -295,12 +295,14 @@ public class Future
private static IntPtr ThenRaw(IntPtr previous, ResolvedCb cb)
{
FutureDesc desc = new FutureDesc();
desc.cb = NativeResolvedCb;
desc.cb = NativeResolvedCbDelegate;
GCHandle handle = GCHandle.Alloc(cb);
desc.data = GCHandle.ToIntPtr(handle);
return eina_future_then_from_desc(previous, desc);
}
private static FutureCb NativeResolvedCbDelegate = new FutureCb(NativeResolvedCb);
private static Eina.ValueNative NativeResolvedCb(IntPtr data, Eina.ValueNative value, IntPtr dead_future)
{
GCHandle handle = GCHandle.FromIntPtr(data);
@ -340,7 +342,7 @@ public class Future
for (; i < cbsList.Count(); i++)
{
ResolvedCb cb = cbsList[i];
descs[i].cb = NativeResolvedCb;
descs[i].cb = NativeResolvedCbDelegate;
GCHandle handle = GCHandle.Alloc(cb);
descs[i].data = GCHandle.ToIntPtr(handle);
}