Skip to content

Commit 5763e5b

Browse files
committed
Add safe interpreter finalization for CPython
Introduced the _finalizeInterpreter function to safely finalize the CPython interpreter without releasing the GIL after Py_FinalizeEx, preventing fatal errors. Updated runPythonProgramInIsolate to use this new function for proper cleanup.
1 parent a0371f9 commit 5763e5b

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

src/serious_python_android/lib/src/cpython.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ T _withGIL<T>(CPython cpython, T Function() action) {
5555
}
5656
}
5757

58+
/// Finalize interpreter safely without releasing GIL afterwards (Py_FinalizeEx
59+
/// tears down the current thread state, so releasing would fatal).
60+
void _finalizeInterpreter(CPython cpython) {
61+
if (cpython.Py_IsInitialized() == 0) {
62+
return;
63+
}
64+
cpython.PyGILState_Ensure();
65+
try {
66+
cpython.Py_FinalizeEx();
67+
_debug("after Py_FinalizeEx()");
68+
} finally {
69+
// Do NOT call PyGILState_Release after finalize; the thread state is gone.
70+
}
71+
}
72+
5873
Future<String> runPythonProgramFFI(bool sync, String dynamicLibPath,
5974
String pythonProgramPath, String script) async {
6075
final receivePort = ReceivePort();
@@ -134,12 +149,7 @@ Future<String> runPythonProgramInIsolate(List<Object> arguments) async {
134149
});
135150
} finally {
136151
// Always finalize interpreter so the next run starts clean and can obtain the GIL.
137-
_withGIL(cpython, () {
138-
if (cpython.Py_IsInitialized() != 0) {
139-
cpython.Py_FinalizeEx();
140-
_debug("after Py_FinalizeEx()");
141-
}
142-
});
152+
_finalizeInterpreter(cpython);
143153
_cpython = null;
144154
}
145155

0 commit comments

Comments
 (0)