Skip to content

Commit

Permalink
Release GCHandle in FSEventStreamContext release callback
Browse files Browse the repository at this point in the history
The callbacks are sometimes delivered even after the FSEventStream is disposed
  • Loading branch information
jkotas committed May 4, 2021
1 parent 89a816f commit 5980ac2
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 7 deletions.
4 changes: 2 additions & 2 deletions src/libraries/Common/src/Interop/OSX/Interop.EventStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ internal struct FSEventStreamContext
{
public CFIndex version;
public IntPtr info;
public IntPtr retainFunc;
public IntPtr releaseFunc;
public IntPtr retain;
public IntPtr release;
public IntPtr copyDescription;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ internal struct SCDynamicStoreContext
{
public CFIndex version;
public IntPtr info;
public IntPtr retainFunc;
public IntPtr releaseFunc;
public IntPtr retain;
public IntPtr release;
public IntPtr copyDescription;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,6 @@ private void CleanupEventStream()

StaticWatcherRunLoopManager.UnscheduleFromRunLoop(eventStream);
eventStream.Dispose();

Debug.Assert(_gcHandle.IsAllocated);
_gcHandle.Free();
}
}

Expand Down Expand Up @@ -314,6 +311,7 @@ internal unsafe void Start(CancellationToken cancellationToken)

Interop.EventStream.FSEventStreamContext context = default;
context.info = GCHandle.ToIntPtr(_gcHandle);
context.release = (IntPtr)(delegate* unmanaged<IntPtr, void>)&ReleaseCallback;

// Create the event stream for the path and tell the stream to watch for file system events.
SafeEventStreamHandle eventStream = Interop.EventStream.FSEventStreamCreate(
Expand All @@ -336,7 +334,10 @@ internal unsafe void Start(CancellationToken cancellationToken)
finally
{
if (cleanupGCHandle)
{
Debug.Assert(_gcHandle.Target is RunningInstance);
_gcHandle.Free();
}
arrPaths?.Dispose();
path?.Dispose();
}
Expand Down Expand Up @@ -373,6 +374,14 @@ internal unsafe void Start(CancellationToken cancellationToken)
}
}

[UnmanagedCallersOnly]
private static void ReleaseCallback(IntPtr clientCallBackInfo)
{
GCHandle gcHandle = GCHandle.FromIntPtr(clientCallBackInfo);
Debug.Assert(gcHandle.Target is RunningInstance);
gcHandle.Free();
}

[UnmanagedCallersOnly]
private static unsafe void FileSystemEventCallback(
FSEventStreamRef streamRef,
Expand Down

0 comments on commit 5980ac2

Please sign in to comment.