Skip to content

Commit adcb3a1

Browse files
committed
Clear all builtin cache on Shutdown
1 parent 04f4841 commit adcb3a1

4 files changed

Lines changed: 40 additions & 10 deletions

File tree

src/runtime/classmanager.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,15 @@ static ClassManager()
3434
dtype = typeof(MulticastDelegate);
3535
}
3636

37+
internal static void Shutdown()
38+
{
39+
foreach (var item in cache.Values)
40+
{
41+
Runtime.Py_DecRef(item.pyHandle);
42+
}
43+
cache.Clear();
44+
}
45+
3746
/// <summary>
3847
/// Return the ClassBase-derived instance that implements a particular
3948
/// reflected managed type, creating it if it doesn't yet exist.
@@ -141,6 +150,8 @@ private static void InitClassBase(Type type, ClassBase impl)
141150
var item = (ManagedType)iter.Value;
142151
var name = (string)iter.Key;
143152
Runtime.PyDict_SetItemString(dict, name, item.pyHandle);
153+
// info.members are already useless
154+
Runtime.Py_DecRef(item.pyHandle);
144155
}
145156

146157
// If class has constructors, generate an __doc__ attribute.
@@ -175,6 +186,7 @@ private static void InitClassBase(Type type, ClassBase impl)
175186
// TODO: deprecate __overloads__ soon...
176187
Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle);
177188
Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle);
189+
Runtime.Py_DecRef(ctors.pyHandle);
178190
}
179191

180192
// don't generate the docstring if one was already set from a DocStringAttribute.

src/runtime/moduleobject.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ public ManagedType GetAttribute(string name, bool guess)
9999
{
100100
m = new ModuleObject(qname);
101101
StoreAttribute(name, m);
102+
Runtime.Py_DecRef(m.pyHandle);
102103
return m;
103104
}
104105

@@ -128,6 +129,7 @@ public ManagedType GetAttribute(string name, bool guess)
128129
{
129130
m = new ModuleObject(qname);
130131
StoreAttribute(name, m);
132+
Runtime.Py_DecRef(m.pyHandle);
131133
return m;
132134
}
133135

@@ -174,7 +176,10 @@ public ManagedType GetAttribute(string name, bool guess)
174176
/// </summary>
175177
private void StoreAttribute(string name, ManagedType ob)
176178
{
177-
Runtime.PyDict_SetItemString(dict, name, ob.pyHandle);
179+
if (Runtime.PyDict_SetItemString(dict, name, ob.pyHandle) != 0)
180+
{
181+
throw new PythonException();
182+
}
178183
cache[name] = ob;
179184
}
180185

@@ -224,6 +229,7 @@ internal void InitializeModuleMembers()
224229
mi[0] = method;
225230
var m = new ModuleFunctionObject(type, name, mi, allow_threads);
226231
StoreAttribute(name, m);
232+
Runtime.Py_DecRef(m.pyHandle);
227233
}
228234
}
229235

@@ -236,6 +242,7 @@ internal void InitializeModuleMembers()
236242
string name = property.Name;
237243
var p = new ModulePropertyObject(property);
238244
StoreAttribute(name, p);
245+
Runtime.Py_DecRef(p.pyHandle);
239246
}
240247
}
241248
type = type.BaseType;

src/runtime/runtime.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public class Runtime
165165
#endif
166166

167167
#if PYTHON_WITH_PYDEBUG
168-
internal const string dllWithPyDebug = "d";
168+
internal const string dllWithPyDebug = "_d";
169169
#else
170170
internal const string dllWithPyDebug = "";
171171
#endif
@@ -356,6 +356,8 @@ internal static void Shutdown()
356356
AssemblyManager.Shutdown();
357357
Exceptions.Shutdown();
358358
ImportHook.Shutdown();
359+
TypeManager.Shutdown();
360+
ClassManager.Shutdown();
359361
Py_Finalize();
360362
}
361363

@@ -638,6 +640,9 @@ internal static unsafe long Refcount(IntPtr op)
638640
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
639641
internal static extern IntPtr PyThreadState_Swap(IntPtr key);
640642

643+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
644+
internal static extern long PyGC_Collect();
645+
641646
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
642647
internal static extern IntPtr PyGILState_Ensure();
643648

@@ -1497,15 +1502,11 @@ internal static bool PyIter_Check(IntPtr pointer)
14971502
internal static extern string PyModule_GetFilename(IntPtr module);
14981503

14991504
#if PYTHON3
1500-
1501-
#if PYTHON_WITH_PYDEBUG
1502-
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl,
1503-
EntryPoint = "PyModule_Create2TraceRefs")]
1504-
internal static extern IntPtr PyModule_Create2(IntPtr module, int apiver);
1505-
#else
15061505
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
15071506
internal static extern IntPtr PyModule_Create2(IntPtr module, int apiver);
1508-
#endif
1507+
1508+
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
1509+
internal static extern IntPtr PyModule_Create2TraceRefs(IntPtr module, int apiver);
15091510

15101511
#endif
15111512

src/runtime/typemanager.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.Reflection;
@@ -21,6 +21,14 @@ static TypeManager()
2121
cache = new Dictionary<Type, IntPtr>(128);
2222
}
2323

24+
internal static void Shutdown()
25+
{
26+
foreach (var item in cache.Values)
27+
{
28+
Runtime.Py_DecRef(item);
29+
}
30+
cache.Clear();
31+
}
2432

2533
/// <summary>
2634
/// Given a managed Type derived from ExtensionType, get the handle to
@@ -352,6 +360,7 @@ internal static IntPtr CreateMetaType(Type impl)
352360
IntPtr dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
353361
IntPtr mod = Runtime.PyString_FromString("CLR");
354362
Runtime.PyDict_SetItemString(dict, "__module__", mod);
363+
Runtime.Py_DecRef(mod);
355364

356365
//DebugUtil.DumpType(type);
357366

@@ -394,6 +403,7 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl)
394403
IntPtr tp_dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
395404
IntPtr mod = Runtime.PyString_FromString("CLR");
396405
Runtime.PyDict_SetItemString(tp_dict, "__module__", mod);
406+
Runtime.Py_DecRef(mod);
397407

398408
return type;
399409
}

0 commit comments

Comments
 (0)