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)
|
private static IntPtr ThenRaw(IntPtr previous, ResolvedCb cb)
|
||||||
{
|
{
|
||||||
FutureDesc desc = new FutureDesc();
|
FutureDesc desc = new FutureDesc();
|
||||||
desc.cb = NativeResolvedCb;
|
desc.cb = NativeResolvedCbDelegate;
|
||||||
GCHandle handle = GCHandle.Alloc(cb);
|
GCHandle handle = GCHandle.Alloc(cb);
|
||||||
desc.data = GCHandle.ToIntPtr(handle);
|
desc.data = GCHandle.ToIntPtr(handle);
|
||||||
return eina_future_then_from_desc(previous, desc);
|
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)
|
private static Eina.ValueNative NativeResolvedCb(IntPtr data, Eina.ValueNative value, IntPtr dead_future)
|
||||||
{
|
{
|
||||||
GCHandle handle = GCHandle.FromIntPtr(data);
|
GCHandle handle = GCHandle.FromIntPtr(data);
|
||||||
|
@ -340,7 +342,7 @@ public class Future
|
||||||
for (; i < cbsList.Count(); i++)
|
for (; i < cbsList.Count(); i++)
|
||||||
{
|
{
|
||||||
ResolvedCb cb = cbsList[i];
|
ResolvedCb cb = cbsList[i];
|
||||||
descs[i].cb = NativeResolvedCb;
|
descs[i].cb = NativeResolvedCbDelegate;
|
||||||
GCHandle handle = GCHandle.Alloc(cb);
|
GCHandle handle = GCHandle.Alloc(cb);
|
||||||
descs[i].data = GCHandle.ToIntPtr(handle);
|
descs[i].data = GCHandle.ToIntPtr(handle);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue