8000 Release method wrapper(split from #958) (#1002) · pythonnet/pythonnet@c1190f4 · GitHub
[go: up one dir, main page]

Skip to content

Commit c1190f4

Browse files
amos402filmor
authored andcommitted
Release method wrapper(split from #958) (#1002)
* Add exception helper * Release memory on ImportHook.Shutdown * Release ModuleDef when py_clr_module released * Completely ModuleDef initialization
1 parent ba5127a commit c1190f4

File tree

5 files changed

+60
-9
lines changed

5 files changed

+60
-9
lines changed

src/runtime/importhook.cs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ internal static void InitializeModuleDef()
2323
module_def = ModuleDefOffset.AllocModuleDef("clr");
2424
}
2525
}
26+
27+
internal static void ReleaseModuleDef()
28+
{
29+
if (module_def == IntPtr.Zero)
30+
{
31+
return;
32+
}
33+
ModuleDefOffset.FreeModuleDef(module_def);
34+
module_def = IntPtr.Zero;
35+
}
2636
#endif
2737

2838
/// <summary>
@@ -56,9 +66,12 @@ static void InitImport()
5666
// Python __import__.
5767
IntPtr builtins = GetNewRefToBuiltins();
5868
py_import = Runtime.PyObject_GetAttrString(builtins, "__import__");
69+
PythonException.ThrowIfIsNull(py_import);
70+
5971
hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc");
60-
Runtime.PyObject_SetAttrString(builtins, "__import__", hook.ptr);
61-
Runtime.XDecref(hook.ptr);
72+
int res = Runtime.PyObject_SetAttrString(builtins, "__import__", hook.ptr);
73+
PythonException.ThrowIfIsNotZero(res);
74+
6275
Runtime.XDecref(builtins);
6376
}
6477

@@ -69,10 +82,14 @@ static void RestoreImport()
6982
{
7083
IntPtr builtins = GetNewRefToBuiltins();
7184

72-
Runtime.PyObject_SetAttrString(builtins, "__import__", py_import);
85+
int res = Runtime.PyObject_SetAttrString(builtins, "__import__", py_import);
86+
PythonException.ThrowIfIsNotZero(res);
7387
Runtime.XDecref(py_import);
7488
py_import = IntPtr.Zero;
7589

90+
hook.Release();
91+
hook = null;
92+
7693
Runtime.XDecref(builtins);
7794
}
7895

@@ -112,13 +129,26 @@ internal static void Initialize()
112129
/// </summary>
113130
internal static void Shutdown()
114131
{
115-
if (Runtime.Py_IsInitialized() != 0)
132+
if (Runtime.Py_IsInitialized() == 0)
116133
{
117-
RestoreImport();
134+
return;
135+
}
118136

119-
Runtime.XDecref(py_clr_module);
120-
Runtime.XDecref(root.pyHandle);
137+
RestoreImport();
138+
139+
bool shouldFreeDef = Runtime.Refcount(py_clr_module) == 1;
140+
Runtime.XDecref(py_clr_module);
141+
py_clr_module = IntPtr.Zero;
142+
#if PYTHON3
143+
if (shouldFreeDef)
144+
{
145+
ReleaseModuleDef();
121146
}
147+
#endif
148+
149+
Runtime.XDecref(root.pyHandle);
150+
root = null;
151+
CLRModule.Reset();
122152
}
123153

124154
/// <summary>

src/runtime/interop.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ public static IntPtr AllocModuleDef(string modulename)
227227
byte[] ascii = Encoding.ASCII.GetBytes(modulename);
228228
int size = name + ascii.Length + 1;
229229
IntPtr ptr = Marshal.AllocHGlobal(size);
230-
for (int i = 0; i < m_free; i += IntPtr.Size)
230+
for (int i = 0; i <= m_free; i += IntPtr.Size)
231231
Marshal.WriteIntPtr(ptr, i, IntPtr.Zero);
232232
Marshal.Copy(ascii, 0, (IntPtr)(ptr + name), ascii.Length);
233233
Marshal.WriteIntPtr(ptr, m_name, (IntPtr)(ptr + name));

src/runtime/methodwrapper.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal class MethodWrapper
1212
{
1313
public IntPtr mdef;
1414
public IntPtr ptr;
15+
private bool _disposed = false;
1516

1617
public MethodWrapper(Type type, string name, string funcType = null)
1718
{
@@ -31,5 +32,21 @@ public IntPtr Call(IntPtr args, IntPtr kw)
3132
{
3233
return Runtime.PyCFunction_Call(ptr, args, kw);
3334
}
35+
36+
public void Release()
37+
{
38+
if (_disposed)
39+
{
40+
return;
41+
}
42+
_disposed = true;
43+
bool freeDef = Runtime.Refcount(ptr) == 1;
44+
Runtime.XDecref(ptr);
45+
if (freeDef && mdef != IntPtr.Zero)
46+
{
47+
Runtime.PyMem_Free(mdef);
48+
mdef = IntPtr.Zero;
49+
}
50+
}
3451
}
3552
}

src/runtime/moduleobject.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ internal class CLRModule : ModuleObject
316316
internal static bool _SuppressDocs = false;
317317
internal static bool _SuppressOverloads = false;
318318

319+
static CLRModule()
320+
{
321+
Reset();
322+
}
323+
319324
public CLRModule() : base("clr")
320325
{
321326
_namespace = string.Empty;

src/runtime/runtime.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ internal static void Initialize(bool initSigs = false)
187187

188188
IsFinalizing = false;
189189

190-
CLRModule.Reset();
191190
GenericUtil.Reset();
192191
PyScopeManager.Reset();
193192
ClassManager.Reset();

0 commit comments

Comments
 (0)
0