10000 Clear ExtensionType · pythonnet/pythonnet@7db724e · GitHub
[go: up one dir, main page]

Skip to content

Commit 7db724e

Browse files
committed
Clear ExtensionType
1 parent b07b844 commit 7db724e

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

src/runtime/extensiontype.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public ExtensionType()
2828

2929
IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);
3030

31-
GCHandle gc = AllocGCHandle();
31+
GCHandle gc = AllocGCHandle(true);
3232
Marshal.WriteIntPtr(py, ObjectOffset.magic(tp), (IntPtr)gc);
3333

3434
// We have to support gc because the type machinery makes it very

src/runtime/managedtype.cs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Runtime.InteropServices;
5+
using System.Linq;
56

67
namespace Python.Runtime
78
{
@@ -16,9 +17,7 @@ internal abstract class ManagedType
1617
internal IntPtr pyHandle; // PyObject *
1718
internal IntPtr tpHandle; // PyType *
1819

19-
#if NPY_TRACK_OBJECT
2020
private static readonly HashSet<ManagedType> _managedObjs = new HashSet<ManagedType>();
21-
#endif
2221

2322
internal void DecrRefCount()
2423
{
@@ -41,22 +40,24 @@ internal long RefCount
4140
}
4241
}
4342

44-
internal GCHandle AllocGCHandle()
43+
internal GCHandle AllocGCHandle(bool track = false)
4544
{
4645
gcHandle = GCHandle.Alloc(this);
47-
#if NPY_TRACK_OBJECT
48-
_managedObjs.Add(this);
49-
#endif
46+
if (track)
47+
{
48+
_managedObjs.Add(this);
49+
}
5050
return gcHandle;
5151
}
5252

5353
internal void FreeGCHandle()
5454
{
55-
gcHandle.Free();
56-
#if NPY_TRACK_OBJECT
5755
_managedObjs.Remove(this);
58-
#endif
59-
gcHandle = new GCHandle();
56+
if (gcHandle.IsAllocated)
57+
{
58+
gcHandle.Free();
59+
gcHandle = new GCHandle();
60+
}
6061
}
6162

6263
/// <summary>
@@ -120,17 +121,15 @@ internal static bool IsManagedType(IntPtr ob)
120121
return false;
121122
}
122123

123-
#if NPY_TRACK_OBJECT
124-
internal static void Reset()
124+
internal static ICollection<ManagedType> GetManagedObjects()
125125
{
126-
_managedObjs.Clear();
126+
return _managedObjs;
127127
}
128128

129-
internal static ICollection<ManagedType> GetManagedObjects()
129+
internal static void ClearTrackedObjects()
130130
{
131-
return _managedObjs;
131+
_managedObjs.Clear();
132132
}
133-
#endif
134133

135134
internal static int PyVisit(IntPtr ob, IntPtr visit, IntPtr arg)
136135
{

src/runtime/runtime.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Threading;
66
using System.Collections.Generic;
77
using Python.Runtime.Platform;
8+
using System.Linq;
89

910
namespace Python.Runtime
1011
{
@@ -384,13 +385,15 @@ internal static void Shutdown(bool soft)
384385
Finalizer.Shutdown();
385386

386387
ClearClrModules();
388+
RemoveClrRootModule();
389+
390+
MoveClrInstancesOnwershipToPython();
387391
ClassManager.RemoveClasses();
388392
TypeManager.RemoveTypes();
389393

390394
MetaType.Release();
391395
PyCLRMetaType = IntPtr.Zero;
392396

393-
RemoveClrRootModule();
394397
if (soft)
395398
{
396399
PyGC_Collect();
@@ -472,6 +475,24 @@ private static void PyDictTryDelItem(IntPtr dict, string key)
472475
PyErr_Clear();
473476
}
474477

478+
private static void MoveClrInstancesOnwershipToPython()
479+
{
480+
var copyObjs = ManagedType.GetManagedObjects().ToArray();
481+
var objs = ManagedType.GetManagedObjects();
482+
foreach (var obj in copyObjs)
483+
{
484+
if (objs.Contains(obj))
485+
{
486+
continue;
487+
}
488+
obj.TypeClear();
489+
PyObject_GC_Track(obj.pyHandle);
490+
obj.gcHandle.Free();
491+
obj.gcHandle = new GCHandle();
492+
}
493+
ManagedType.ClearTrackedObjects();
494+
}
495+
475496

476497
internal static IntPtr Py_single_input = (IntPtr)256;
477498
internal static IntPtr Py_file_input = (IntPtr)257;

0 commit comments

Comments
 (0)
0