Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[.NET/CoreFoundation] Use [UnmanagedCallersOnly] instead of [MonoPInvokeCallback] Partial Fix for #10470 #15879

Merged
merged 1 commit into from
Sep 7, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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