@@ -46,6 +46,15 @@ void _debug(String message) {
4646 debugPrint ("[serious_python] $message " );
4747}
4848
49+ T _withGIL <T >(CPython cpython, T Function () action) {
50+ final gil = cpython.PyGILState_Ensure ();
51+ try {
52+ return action ();
53+ } finally {
54+ cpython.PyGILState_Release (gil);
55+ }
56+ }
57+
4958Future <String > runPythonProgramFFI (bool sync , String dynamicLibPath,
5059 String pythonProgramPath, String script) async {
5160 final receivePort = ReceivePort ();
@@ -87,7 +96,7 @@ Future<String> runPythonProgramInIsolate(List<Object> arguments) async {
8796 _debug ("after Py_Initialize()" );
8897 }
8998
90- final logcatSetupError = _setupLogcatForwarding (cpython);
99+ final logcatSetupError = _withGIL (cpython, () => _setupLogcatForwarding (cpython) );
91100 if (logcatSetupError != null ) {
92101 sendPort.send (logcatSetupError);
93102 return logcatSetupError;
@@ -97,23 +106,31 @@ Future<String> runPythonProgramInIsolate(List<Object> arguments) async {
97106
98107 if (script != "" ) {
99108 // run script
100- _debug ("Running script: $script " );
101- final scriptPtr = script.toNativeUtf8 ();
102- int sr = cpython.PyRun_SimpleString (scriptPtr.cast <Char >());
103- _debug ("PyRun_SimpleString for script result: $sr " );
104- malloc.free (scriptPtr);
105- if (sr != 0 ) {
106- result = getPythonError (cpython);
107- }
109+ result = _withGIL (cpython, () {
110+ _debug ("Running script: $script " );
111+ final scriptPtr = script.toNativeUtf8 ();
112+ int sr = cpython.PyRun_SimpleString (scriptPtr.cast <Char >());
113+ _debug ("PyRun_SimpleString for script result: $sr " );
114+ malloc.free (scriptPtr);
115+ if (sr != 0 ) {
116+ return getPythonError (cpython);
117+ }
118+ return "" ;
119+ });
108120 } else {
109121 // run program
110- _debug ("Running program module: $programModuleName " );
111- final moduleNamePtr = programModuleName.toNativeUtf8 ();
112- var modulePtr = cpython.PyImport_ImportModule (moduleNamePtr.cast <Char >());
113- if (modulePtr == nullptr) {
114- result = getPythonError (cpython);
115- }
116- malloc.free (moduleNamePtr);
122+ result = _withGIL (cpython, () {
123+ _debug ("Running program module: $programModuleName " );
124+ final moduleNamePtr = programModuleName.toNativeUtf8 ();
125+ var modulePtr = cpython.PyImport_ImportModule (moduleNamePtr.cast <Char >());
126+ if (modulePtr == nullptr) {
127+ final error = getPythonError (cpython);
128+ malloc.free (moduleNamePtr);
129+ return error;
130+ }
131+ malloc.free (moduleNamePtr);
132+ return "" ;
133+ });
117134 }
118135
119136 _debug ("Python program finished" );
@@ -125,38 +142,41 @@ Future<String> runPythonProgramInIsolate(List<Object> arguments) async {
125142
126143String getPythonError (CPython cpython) {
127144 // get error object
128- var exPtr = cpython.PyErr_GetRaisedException ();
145+ var exPtr = _withGIL ( cpython, () => cpython .PyErr_GetRaisedException () );
129146
130147 // use 'traceback' module to format exception
131148 final tracebackModuleNamePtr = "traceback" .toNativeUtf8 ();
132- var tracebackModulePtr =
133- cpython.PyImport_ImportModule (tracebackModuleNamePtr.cast <Char >());
149+ var tracebackModulePtr = _withGIL (cpython,
150+ () => cpython.PyImport_ImportModule (tracebackModuleNamePtr.cast <Char >() ));
134151 cpython.Py_DecRef (tracebackModuleNamePtr.cast ());
135152
136153 if (tracebackModulePtr != nullptr) {
137154 //_debug("Traceback module loaded");
138155
139156 final formatFuncName = "format_exception" .toNativeUtf8 ();
140- final pFormatFunc = cpython.PyObject_GetAttrString (
141- tracebackModulePtr, formatFuncName.cast ());
157+ final pFormatFunc = _withGIL (
158+ cpython,
159+ () => cpython.PyObject_GetAttrString (
160+ tracebackModulePtr, formatFuncName.cast ()));
142161 cpython.Py_DecRef (tracebackModuleNamePtr.cast ());
143162
144163 if (pFormatFunc != nullptr && cpython.PyCallable_Check (pFormatFunc) != 0 ) {
145164 // call `traceback.format_exception()` method
146- final pArgs = cpython.PyTuple_New (1 );
147- cpython.PyTuple_SetItem (pArgs, 0 , exPtr);
165+ final pArgs = _withGIL ( cpython, () => cpython .PyTuple_New (1 ) );
166+ _withGIL ( cpython, () => cpython .PyTuple_SetItem (pArgs, 0 , exPtr) );
148167
149168 // result is a list
150- var listPtr = cpython.PyObject_CallObject (pFormatFunc, pArgs);
169+ var listPtr =
170+ _withGIL (cpython, () => cpython.PyObject_CallObject (pFormatFunc, pArgs));
151171
152172 // get and combine list items
153173 var exLines = [];
154- var listSize = cpython.PyList_Size (listPtr);
174+ var listSize = _withGIL ( cpython, () => cpython .PyList_Size (listPtr) );
155175 for (var i = 0 ; i < listSize; i++ ) {
156- var itemObj = cpython.PyList_GetItem (listPtr, i);
157- var itemObjStr = cpython.PyObject_Str (itemObj);
158- var s =
159- cpython.PyUnicode_AsUTF8 (itemObjStr).cast <Utf8 >().toDartString ();
176+ var itemObj = _withGIL ( cpython, () => cpython .PyList_GetItem (listPtr, i) );
177+ var itemObjStr = _withGIL ( cpython, () => cpython .PyObject_Str (itemObj) );
178+ var s = _withGIL (cpython,
179+ () => cpython.PyUnicode_AsUTF8 (itemObjStr).cast <Utf8 >().toDartString () );
160180 exLines.add (s);
161181 }
162182 return exLines.join ("" );
0 commit comments