Skip to content

Commit 1b71ee0

Browse files
author
wonder
committedOct 25, 2010
Make calls to python api safer by ensuring we have global interpreter lock
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14434 c8812cc2-4d05-0410-92ff-de0c093fc19c

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed
 

‎src/python/qgspythonutilsimpl.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,21 @@ void QgsPythonUtilsImpl::uninstallErrorHook()
139139

140140
bool QgsPythonUtilsImpl::runStringUnsafe( const QString& command, bool single )
141141
{
142+
// acquire global interpreter lock to ensure we are in a consistent state
143+
PyGILState_STATE gstate;
144+
gstate = PyGILState_Ensure();
145+
142146
// TODO: convert special characters from unicode strings u"..." to \uXXXX
143147
// so that they're not mangled to utf-8
144148
// (non-unicode strings can be mangled)
145149
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;
147157
}
148158

149159
bool QgsPythonUtilsImpl::runString( const QString& command, QString msgOnError )
@@ -184,6 +194,9 @@ QString QgsPythonUtilsImpl::getTraceback()
184194
{
185195
#define TRACEBACK_FETCH_ERROR(what) {errMsg = what; goto done;}
186196

197+
// acquire global interpreter lock to ensure we are in a consistent state
198+
PyGILState_STATE gstate;
199+
gstate = PyGILState_Ensure();
187200

188201
QString errMsg;
189202
QString result;
@@ -249,6 +262,9 @@ QString QgsPythonUtilsImpl::getTraceback()
249262
Py_XDECREF( traceback );
250263
Py_XDECREF( type );
251264

265+
// we are done calling python API, release global interpreter lock
266+
PyGILState_Release( gstate );
267+
252268
return result;
253269
}
254270

@@ -276,8 +292,15 @@ QString QgsPythonUtilsImpl::getTypeAsString( PyObject* obj )
276292

277293
bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
278294
{
295+
// acquire global interpreter lock to ensure we are in a consistent state
296+
PyGILState_STATE gstate;
297+
gstate = PyGILState_Ensure();
298+
279299
if ( !PyErr_Occurred() )
300+
{
301+
PyGILState_Release( gstate );
280302
return false;
303+
}
281304

282305
PyObject* err_type;
283306
PyObject* err_value;
@@ -302,6 +325,9 @@ bool QgsPythonUtilsImpl::getError( QString& errorClassName, QString& errorText )
302325
Py_XDECREF( err_value );
303326
Py_XDECREF( err_tb );
304327

328+
// we are done calling python API, release global interpreter lock
329+
PyGILState_Release( gstate );
330+
305331
return true;
306332
}
307333

@@ -369,16 +395,22 @@ QString QgsPythonUtilsImpl::PyObjectToQString( PyObject* obj )
369395

370396
bool QgsPythonUtilsImpl::evalString( const QString& command, QString& result )
371397
{
398+
// acquire global interpreter lock to ensure we are in a consistent state
399+
PyGILState_STATE gstate;
400+
gstate = PyGILState_Ensure();
401+
372402
PyObject* res = PyRun_String( command.toUtf8().data(), Py_eval_input, mMainDict, mMainDict );
403+
bool success = ( res != NULL );
373404

374405
// TODO: error handling
375406

376-
if ( res != NULL )
377-
{
407+
if ( success )
378408
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;
382414
}
383415

384416

0 commit comments

Comments
 (0)
Please sign in to comment.