Skip to content

Commit

Permalink
[.NET/CoreFoundation] Use [UnmanagedCallersOnly] instead of [MonoPInv…
Browse files Browse the repository at this point in the history
…okeCallback] Partial Fix for #10470 (#15879)
  • Loading branch information
stephen-hawley authored Sep 7, 2022
1 parent c5615ae commit 6590c11
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/CoreFoundation/CFRunLoop.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,27 @@ public enum CFRunLoopExitReason : int {

// CFRunLoop.h
[StructLayout (LayoutKind.Sequential)]
#if NET
internal unsafe struct CFRunLoopSourceContext {
#else
internal struct CFRunLoopSourceContext {
#endif
public CFIndex Version;
public IntPtr Info;
public IntPtr Retain;
public IntPtr Release;
public IntPtr CopyDescription;
public IntPtr Equal;
public IntPtr Hash;
#if NET
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Schedule;
public delegate* unmanaged<IntPtr, IntPtr, IntPtr, void> Cancel;
public delegate* unmanaged<IntPtr, void> Perform;
#else
public IntPtr Schedule;
public IntPtr Cancel;
public IntPtr Perform;
#endif
}

#if NET
Expand Down Expand Up @@ -145,27 +155,41 @@ public abstract class CFRunLoopSourceCustom : CFRunLoopSource {
[DllImport (Constants.CoreFoundationLibrary)]
extern static /* CFRunLoopSourceRef */ IntPtr CFRunLoopSourceCreate (/* CFAllocatorRef */ IntPtr allocator, /* CFIndex */ nint order, /* CFRunLoopSourceContext* */ ref CFRunLoopSourceContext context);

#if !NET
static ScheduleCallback ScheduleDelegate = (ScheduleCallback) Schedule;
static CancelCallback CancelDelegate = (CancelCallback) Cancel;
static PerformCallback PerformDelegate = (PerformCallback) Perform;
#endif

protected CFRunLoopSourceCustom ()
: base (IntPtr.Zero, true)
{
gch = GCHandle.Alloc (this);
var ctx = new CFRunLoopSourceContext ();
ctx.Info = GCHandle.ToIntPtr (gch);
#if NET
unsafe {
ctx.Schedule = &Schedule;
ctx.Cancel = &Cancel;
ctx.Perform = &Perform;
}
#else
ctx.Schedule = Marshal.GetFunctionPointerForDelegate (ScheduleDelegate);
ctx.Cancel = Marshal.GetFunctionPointerForDelegate (CancelDelegate);
ctx.Perform = Marshal.GetFunctionPointerForDelegate (PerformDelegate);
#endif

var handle = CFRunLoopSourceCreate (IntPtr.Zero, 0, ref ctx);
InitializeHandle (handle);
}

delegate void ScheduleCallback (IntPtr info, IntPtr runLoop, IntPtr mode);

#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(ScheduleCallback))]
#endif
static void Schedule (IntPtr info, IntPtr runLoop, IntPtr mode)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
Expand All @@ -182,7 +206,11 @@ static void Schedule (IntPtr info, IntPtr runLoop, IntPtr mode)

delegate void CancelCallback (IntPtr info, IntPtr runLoop, IntPtr mode);

#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(CancelCallback))]
#endif
static void Cancel (IntPtr info, IntPtr runLoop, IntPtr mode)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
Expand All @@ -199,7 +227,11 @@ static void Cancel (IntPtr info, IntPtr runLoop, IntPtr mode)

delegate void PerformCallback (IntPtr info);

#if NET
[UnmanagedCallersOnly]
#else
[MonoPInvokeCallback (typeof(PerformCallback))]
#endif
static void Perform (IntPtr info)
{
var source = GCHandle.FromIntPtr (info).Target as CFRunLoopSourceCustom;
Expand Down

6 comments on commit 6590c11

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.