8000 made freeing GCHandles more robust · pythonnet/pythonnet@ab11fa2 · GitHub
[go: up one dir, main page]

Skip to content

Commit ab11fa2

Browse files
committed
made freeing GCHandles more robust
1 parent 7167229 commit ab11fa2

File tree

5 files changed

+28
-21
lines changed

5 files changed

+28
-21
lines changed

src/runtime/classbase.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,7 @@ public static void tp_dealloc(NewReference lastRef)
350350

351351
public static int tp_clear(BorrowedReference ob)
352352
{
353-
GCHandle? gcHandle = TryGetGCHandle(ob);
354-
gcHandle?.Free();
353+
TryFreeGCHandle(ob);
355354

356355
int baseClearResult = BaseUnmanagedClear(ob);
357356
if (baseClearResult != 0)

src/runtime/extensiontype.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,7 @@ public unsafe static void tp_dealloc(NewReference lastRef)
8989

9090
public static int tp_clear(BorrowedReference ob)
9191
{
92-
GCHandle? gcHandle = TryGetGCHandle(ob);
93-
gcHandle?.Free();
94-
if (gcHandle is not null) SetGCHandle(ob, default);
92+
TryFreeGCHandle(ob);
9593

9694
int res = ClassBase.BaseUnmanagedClear(ob);
9795
return res;

src/runtime/managedtype.cs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal abstract class ManagedType
2525
var flags = PyType.GetFlags(tp);
2626
if ((flags & TypeFlags.HasClrInstance) != 0)
2727
{
28-
var gc = TryGetGCHandle(ob);
28+
var gc = TryGetGCHandle(ob, tp);
2929
return (ManagedType?)gc?.Target;
3030
}
3131
}
@@ -193,6 +193,7 @@ internal static void SetGCHandle(BorrowedReference reflectedClrObject, BorrowedR
193193
{
194194
Debug.Assert(type != null);
195195
Debug.Assert(reflectedClrObject != null);
196+
Debug.Assert(IsManagedType(type) || IsManagedType(reflectedClrObject));
196197
Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type));
197198

198199
int offset = Util.ReadInt32(type, Offsets.tp_clr_inst_offset);
@@ -203,6 +204,28 @@ internal static void SetGCHandle(BorrowedReference reflectedClrObject, BorrowedR
203204
internal static void SetGCHandle(BorrowedReference reflectedClrObject, GCHandle newHandle)
204205
=> SetGCHandle(reflectedClrObject, Runtime.PyObject_TYPE(reflectedClrObject), newHandle);
205206

207+
internal static bool TryFreeGCHandle(BorrowedReference reflectedClrObject)
208+
=> TryFreeGCHandle(reflectedClrObject, Runtime.PyObject_TYPE(reflectedClrObject));
209+
210+
internal static bool TryFreeGCHandle(BorrowedReference reflectedClrObject, BorrowedReference type)
211+
{
212+
Debug.Assert(type != null);
213+
Debug.Assert(reflectedClrObject != null);
214+
Debug.Assert(IsManagedType(type) || IsManagedType(reflectedClrObject));
215+
Debug.Assert(Runtime.PyObject_TypeCheck(reflectedClrObject, type));
216+
217+
int offset = Util.ReadInt32(type, Offsets.tp_clr_inst_offset);
218+
Debug.Assert(offset > 0);
219+
220+
IntPtr raw = Util.ReadIntPtr(reflectedClrObject, offset);
221+
if (raw == IntPtr.Zero) return false;
222+
223+
((GCHandle)raw).Free();
224+
225+
Util.WriteIntPtr(reflectedClrObject, offset, IntPtr.Zero);
226+
return true;
227+
}
228+
206229
internal static class Offsets
207230
{
208231
static Offsets()

src/runtime/runtime.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -532,12 +532,7 @@ private static void MoveClrInstancesOnwershipToPython()
532532
)
533533
{
534534
var @ref = new BorrowedReference(objWithGcHandle);
535-
GCHandle? handle = ManagedType.TryGetGCHandle(@ref);
536-
handle?.Free();
537-
if (handle is not null)
538-
{
539-
ManagedType.SetGCHandle(@ref, default);
540-
}
535+
ManagedType.TryFreeGCHandle(@ref);
541536
}
542537

543538
//foreach (IntPtr extensionAddr in ExtensionType.loadedExtensions.ToArray())

src/runtime/typemanager.cs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -823,15 +823,7 @@ public void ResetSlots()
823823
if (Type != Runtime.CLRMetaType)
824824
{
825825
var metatype = Runtime.PyObject_TYPE(Type);
826-
if (ManagedType.TryGetGCHandle(Type, metatype) is { } handle)
827-
{
828-
if (handle.IsAllocated)
829-
{
830-
handle.Free();
831-
}
832-
833-
ManagedType.SetGCHandle(Type, metatype, default);
834-
}
826+
ManagedType.TryFreeGCHandle(Type, metatype);
835827
}
836828
}
837829

0 commit comments

Comments
 (0)
0