-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Add GCHandle<T> #111307
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
Add GCHandle<T> #111307
Changes from all commits
4912b81
34667f6
0b92685
b533663
a443880
37c22a5
7e9dcab
daa2d71
3d6c6cc
6e3a26e
52a892e
cd45974
06f7298
af5be56
948b665
4c82bfe
80a8580
c25bf1b
8dee06a
e73f07c
433047e
47b5017
39752af
5510296
d3a3a28
0a8485d
86e9d93
cf4add9
5907d3c
1b0bf88
3b1a097
ec98a74
cf45bcd
3598aa0
1337d04
43859e2
6c80e1b
c8a9497
f8d0158
42c6362
d7800bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -100,7 +100,7 @@ private static ConditionalWeakTable<Delegate, PInvokeDelegateThunk> GetPInvokeDe | |
| [StructLayout(LayoutKind.Sequential, Pack = 1)] | ||
| internal unsafe struct ThunkContextData | ||
| { | ||
| public GCHandle Handle; // A weak GCHandle to the delegate | ||
| public WeakGCHandle<Delegate> Handle; // A weak GCHandle to the delegate | ||
| public IntPtr FunctionPtr; // Function pointer for open static delegates | ||
| } | ||
|
|
||
|
|
@@ -133,7 +133,7 @@ public PInvokeDelegateThunk(Delegate del) | |
| ThunkContextData* thunkData = (ThunkContextData*)ContextData; | ||
|
|
||
| // allocate a weak GChandle for the delegate | ||
| thunkData->Handle = GCHandle.Alloc(del, GCHandleType.WeakTrackResurrection); | ||
| thunkData->Handle = new WeakGCHandle<Delegate>(del, trackResurrection: true); | ||
| thunkData->FunctionPtr = openStaticFunctionPointer; | ||
| } | ||
|
|
||
|
|
@@ -148,17 +148,17 @@ public PInvokeDelegateThunk(Delegate del) | |
| if (ContextData != IntPtr.Zero) | ||
| { | ||
| // free the GCHandle | ||
| GCHandle handle = ((ThunkContextData*)ContextData)->Handle; | ||
| WeakGCHandle<Delegate> handle = ((ThunkContextData*)ContextData)->Handle; | ||
| if (handle.IsAllocated) | ||
| { | ||
| // If the delegate is still alive, defer finalization. | ||
| if (handle.Target != null) | ||
| if (handle.TryGetTarget(out _)) | ||
| { | ||
| GC.ReRegisterForFinalize(this); | ||
| return; | ||
| } | ||
|
|
||
| handle.Free(); | ||
| handle.Dispose(); | ||
| } | ||
|
|
||
| // Free the allocated context data memory | ||
|
|
@@ -205,21 +205,20 @@ private static unsafe PInvokeDelegateThunk AllocateThunk(Delegate del) | |
| IntPtr pTarget; | ||
| if (s_thunkPoolHeap != null && RuntimeAugments.TryGetThunkData(s_thunkPoolHeap, ptr, out pContext, out pTarget)) | ||
| { | ||
| GCHandle handle; | ||
| WeakGCHandle<Delegate> handle; | ||
| unsafe | ||
| { | ||
| // Pull out Handle from context | ||
| handle = ((ThunkContextData*)pContext)->Handle; | ||
| } | ||
| Delegate target = Unsafe.As<Delegate>(handle.Target); | ||
|
|
||
| // | ||
| // The delegate might already been garbage collected | ||
| // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive | ||
| // until they are done with the native function pointer | ||
| // | ||
| if (target == null) | ||
| if (!handle.TryGetTarget(out Delegate? target)) | ||
| { | ||
| // | ||
| // The delegate might already been garbage collected | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "might have"... what situation would result in TryGetTarget being false here but because of some reason other than GC?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The comment was copied from old one. Maybe it's saying in the context of the whole method? |
||
| // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive | ||
| // until they are done with the native function pointer | ||
| // | ||
| Environment.FailFast(SR.Delegate_GarbageCollected); | ||
| } | ||
|
|
||
|
|
@@ -269,7 +268,7 @@ public static IntPtr GetCurrentCalleeOpenStaticDelegateFunctionPointer() | |
| /// <summary> | ||
| /// Retrieves the current delegate that is being called | ||
| /// </summary> | ||
| public static T GetCurrentCalleeDelegate<T>() where T : class // constraint can't be System.Delegate | ||
| public static T GetCurrentCalleeDelegate<T>() where T : Delegate | ||
MichalStrehovsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| { | ||
| // | ||
| // RH keeps track of the current thunk that is being called through a secret argument / thread | ||
|
|
@@ -280,26 +279,25 @@ public static T GetCurrentCalleeDelegate<T>() where T : class // constraint can' | |
|
|
||
| Debug.Assert(pContext != IntPtr.Zero); | ||
|
|
||
| GCHandle handle; | ||
| WeakGCHandle<Delegate> handle; | ||
| unsafe | ||
| { | ||
| // Pull out Handle from context | ||
| handle = ((ThunkContextData*)pContext)->Handle; | ||
|
|
||
| } | ||
|
|
||
| T target = Unsafe.As<T>(handle.Target); | ||
|
|
||
| // | ||
| // The delegate might already been garbage collected | ||
| // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive | ||
| // until they are done with the native function pointer | ||
| // | ||
| if (target == null) | ||
| if (!handle.TryGetTarget(out Delegate? target)) | ||
| { | ||
| // | ||
| // The delegate might already been garbage collected | ||
| // User should use GC.KeepAlive or whatever ways necessary to keep the delegate alive | ||
| // until they are done with the native function pointer | ||
| // | ||
| Environment.FailFast(SR.Delegate_GarbageCollected); | ||
| } | ||
| return target; | ||
|
|
||
| return Unsafe.As<T>(target); | ||
| } | ||
| #endregion | ||
|
|
||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.