@@ -139,11 +139,21 @@ void QgsPythonUtilsImpl::uninstallErrorHook()
139
139
140
140
bool QgsPythonUtilsImpl::runStringUnsafe ( const QString& command, bool single )
141
141
{
142
+ // acquire global interpreter lock to ensure we are in a consistent state
143
+ PyGILState_STATE gstate;
144
+ gstate = PyGILState_Ensure ();
145
+
142
146
// TODO: convert special characters from unicode strings u"..." to \uXXXX
143
147
// so that they're not mangled to utf-8
144
148
// (non-unicode strings can be mangled)
145
149
PyRun_String ( command.toUtf8 ().data (), single ? Py_single_input : Py_file_input, mMainDict , mMainDict );
146
- return ( PyErr_Occurred () == 0 );
150
+
151
+ bool res = ( PyErr_Occurred () == 0 );
152
+
153
+ // we are done calling python API, release global interpreter lock
154
+ PyGILState_Release ( gstate );
155
+
156
+ return res;
147
157
}
148
158
149
159
bool QgsPythonUtilsImpl::runString ( const QString& command, QString msgOnError )
@@ -184,6 +194,9 @@ QString QgsPythonUtilsImpl::getTraceback()
184
194
{
185
195
#define TRACEBACK_FETCH_ERROR (what ) {errMsg = what; goto done;}
186
196
197
+ // acquire global interpreter lock to ensure we are in a consistent state
198
+ PyGILState_STATE gstate;
199
+ gstate = PyGILState_Ensure ();
187
200
188
201
QString errMsg;
189
202
QString result;
@@ -249,6 +262,9 @@ QString QgsPythonUtilsImpl::getTraceback()
249
262
Py_XDECREF ( traceback );
250
263
Py_XDECREF ( type );
251
264
265
+ // we are done calling python API, release global interpreter lock
266
+ PyGILState_Release ( gstate );
267
+
252
268
return result;
253
269
}
254
270
@@ -276,8 +292,15 @@ QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
276
292
277
293
bool QgsPythonUtilsImpl::getError ( QString& errorClassName, QString& errorText )
278
294
{
295
+ // acquire global interpreter lock to ensure we are in a consistent state
296
+ PyGILState_STATE gstate;
297
+ gstate = PyGILState_Ensure ();
298
+
279
299
if ( !PyErr_Occurred () )
300
+ {
301
+ PyGILState_Release ( gstate );
280
302
return false ;
303
+ }
281
304
282
305
PyObject* err_type;
283
306
PyObject* err_value;
@@ -302,6 +325,9 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
302
325
Py_XDECREF ( err_value );
303
326
Py_XDECREF ( err_tb );
304
327
328
+ // we are done calling python API, release global interpreter lock
329
+ PyGILState_Release ( gstate );
330
+
305
331
return true ;
306
332
}
307
333
@@ -369,16 +395,22 @@ QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
369
395
370
396
bool QgsPythonUtilsImpl::evalString ( const QString& command, QString& result )
371
397
{
398
+ // acquire global interpreter lock to ensure we are in a consistent state
399
+ PyGILState_STATE gstate;
400
+ gstate = PyGILState_Ensure ();
401
+
372
402
PyObject* res = PyRun_String ( command.toUtf8 ().data (), Py_eval_input, mMainDict , mMainDict );
403
+ bool success = ( res != NULL );
373
404
374
405
// TODO: error handling
375
406
376
- if ( res != NULL )
377
- {
407
+ if ( success )
378
408
result = PyObjectToQString ( res );
379
- return true ;
380
- }
381
- return false ;
409
+
410
+ // we are done calling python API, release global interpreter lock
411
+ PyGILState_Release ( gstate );
412
+
413
+ return success;
382
414
}
383
415
384
416
0 commit comments