forked from enlightenment/efl
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:
parent
73df0d47ff
commit
00a1a203a5
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue