Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Letwory <nathan@letworyinteractive.com>2008-02-23 15:05:28 +0300
committerNathan Letwory <nathan@letworyinteractive.com>2008-02-23 15:05:28 +0300
commit012f0a336c84b22c3e20716e4820f3342afef5d3 (patch)
tree00170e02918c2ae92c1c9a3b6e6145c01f954a15 /source/blender/python
parent206021113da61f352d96805af7e82e9d41dd70b9 (diff)
=== PyNodes ===
* Make PyNodes work with threaded renderer. This patch is by Willian. He has worked hard on getting this sorted out - now you should be able to render with PyNodes AND multiple threads.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/BPY_interface.c198
-rw-r--r--source/blender/python/api2_2x/Draw.c16
-rw-r--r--source/blender/python/api2_2x/Window.c6
3 files changed, 196 insertions, 24 deletions
diff --git a/source/blender/python/BPY_interface.c b/source/blender/python/BPY_interface.c
index 9d28e8f9e38..b1fd48d87e6 100644
--- a/source/blender/python/BPY_interface.c
+++ b/source/blender/python/BPY_interface.c
@@ -182,6 +182,7 @@ PyObject *traceback_getFilename( PyObject * tb );
****************************************************************************/
void BPY_start_python( int argc, char **argv )
{
+ PyThreadState *py_tstate = NULL;
static int argc_copy = 0;
static char **argv_copy = NULL;
int first_time = argc;
@@ -227,6 +228,9 @@ void BPY_start_python( int argc, char **argv )
Py_Initialize( );
PySys_SetArgv( argc_copy, argv_copy );
+ /* Initialize thread support (also acquires lock) */
+ PyEval_InitThreads();
+
//Overrides __import__
init_ourImport( );
init_ourReload( );
@@ -237,6 +241,10 @@ void BPY_start_python( int argc, char **argv )
//Look for a python installation
init_syspath( first_time ); /* not first_time: some msgs are suppressed */
+ //PyEval_ReleaseLock();
+ py_tstate = PyGILState_GetThisThreadState();
+ PyEval_ReleaseThread(py_tstate);
+
return;
}
@@ -247,6 +255,8 @@ void BPY_end_python( void )
{
Script *script = NULL;
+ PyGILState_Ensure(); /* finalizing, no need to grab the state */
+
if( bpy_registryDict ) {
Py_DECREF( bpy_registryDict );
bpy_registryDict = NULL;
@@ -392,7 +402,6 @@ void init_syspath( int first_time )
}
}
-
void BPY_rebuild_syspath( void )
{
PyObject *mod, *dict, *syspath;
@@ -444,6 +453,7 @@ void BPY_rebuild_syspath( void )
}
Py_DECREF(mod);
+
}
/****************************************************************************
@@ -457,8 +467,12 @@ that dir info is available.
****************************************************************************/
void BPY_post_start_python( void )
{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
BPY_rebuild_syspath();
BPyMenu_Init( 0 ); /* get dynamic menus (registered scripts) data */
+
+ PyGILState_Release(gilstate);
}
/****************************************************************************
@@ -599,6 +613,7 @@ int BPY_txt_do_python_Text( struct Text *text )
BPy_constant *info;
char textname[24];
Script *script = G.main->script.first;
+ PyGILState_STATE gilstate;
if( !text )
return 0;
@@ -639,10 +654,13 @@ int BPY_txt_do_python_Text( struct Text *text )
script->py_button = NULL;
script->py_browsercallback = NULL;
+ gilstate = PyGILState_Ensure();
+
py_dict = CreateGlobalDictionary( );
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict\n");
+ PyGILState_Release(gilstate);
return 0;
}
@@ -667,7 +685,7 @@ int BPY_txt_do_python_Text( struct Text *text )
script->py_globaldict = NULL;
if( G.main->script.first )
free_libblock( &G.main->script, script );
-
+ PyGILState_Release(gilstate);
return 0;
} else {
Py_DECREF( py_result );
@@ -679,6 +697,8 @@ int BPY_txt_do_python_Text( struct Text *text )
}
}
+ PyGILState_Release(gilstate);
+
return 1; /* normal return */
}
@@ -759,12 +779,15 @@ int BPY_menu_do_python( short menutype, int event )
char scriptname[21];
Script *script = NULL;
int len;
+ PyGILState_STATE gilstate;
pym = BPyMenu_GetEntry( menutype, ( short ) event );
if( !pym )
return 0;
+ gilstate = PyGILState_Ensure();
+
if( pym->version > G.version )
notice( "Version mismatch: script was written for Blender %d. "
"It may fail with yours: %d.", pym->version,
@@ -787,8 +810,10 @@ int BPY_menu_do_python( short menutype, int event )
while( arg-- )
pysm = pysm->next;
pyarg = PyString_FromString( pysm->arg );
- } else
+ } else {
+ PyGILState_Release(gilstate);
return 0;
+ }
}
}
@@ -810,6 +835,7 @@ int BPY_menu_do_python( short menutype, int event )
if (!scriptsdir) {
printf("Error loading script: can't find default scripts dir!");
+ PyGILState_Release(gilstate);
return 0;
}
@@ -820,6 +846,7 @@ int BPY_menu_do_python( short menutype, int event )
if( !fp ) {
printf( "Error loading script: couldn't open file %s\n",
filestr );
+ PyGILState_Release(gilstate);
return 0;
}
@@ -838,6 +865,7 @@ int BPY_menu_do_python( short menutype, int event )
if( !script ) {
printf( "couldn't allocate memory for Script struct!" );
fclose( fp );
+ PyGILState_Release(gilstate);
return 0;
}
@@ -944,6 +972,7 @@ int BPY_menu_do_python( short menutype, int event )
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict\n");
MEM_freeN( buffer );
+ PyGILState_Release(gilstate);
return 0;
}
@@ -962,6 +991,7 @@ int BPY_menu_do_python( short menutype, int event )
free_libblock( &G.main->script, script );
error( "Python script error: check console" );
+ PyGILState_Release(gilstate);
return 0;
} else {
Py_DECREF( py_res );
@@ -983,6 +1013,8 @@ int BPY_menu_do_python( short menutype, int event )
}
}
+ PyGILState_Release(gilstate);
+
return 1; /* normal return */
}
@@ -1005,14 +1037,20 @@ void BPY_free_compiled_text( struct Text *text )
*****************************************************************************/
void BPY_free_finished_script( Script * script )
{
+ PyGILState_STATE gilstate;
+
if( !script )
return;
+ gilstate = PyGILState_Ensure();
+
if( PyErr_Occurred( ) ) { /* if script ended after filesel */
PyErr_Print( ); /* eventual errors are handled now */
error( "Python script error: check console" );
}
+ PyGILState_Release(gilstate);
+
free_libblock( &G.main->script, script );
return;
}
@@ -1047,13 +1085,17 @@ static void unlink_script( Script * script )
void BPY_clear_script( Script * script )
{
PyObject *dict;
+ PyGILState_STATE gilstate;
if( !script )
return;
+ gilstate = PyGILState_Ensure();
+
if (!Py_IsInitialized()) {
printf("\nError: trying to free script data after finalizing Python!");
printf("\nScript name: %s\n", script->id.name+2);
+ PyGILState_Release(gilstate);
return;
}
@@ -1074,6 +1116,8 @@ void BPY_clear_script( Script * script )
script->py_globaldict = NULL;
}
+ PyGILState_Release(gilstate);
+
unlink_script( script );
}
@@ -1229,11 +1273,14 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
/* script does exist. it is assumed that this is a valid pyconstraint script */
PyObject *globals;
PyObject *retval, *gval;
+ PyGILState_STATE gilstate;
int num, i;
/* clear the relevant flags first */
data->flag = 0;
-
+
+ gilstate = PyGILState_Ensure();
+
/* populate globals dictionary */
globals = CreateGlobalDictionary();
retval = RunPython(data->text, globals);
@@ -1242,6 +1289,7 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
BPY_Err_Handle(data->text->id.name);
ReleaseGlobalDictionary(globals);
data->flag |= PYCON_SCRIPTERROR;
+ PyGILState_Release(gilstate);
return;
}
@@ -1297,6 +1345,10 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
/* clear globals */
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
+ return;
}
else {
/* NUM_TARGETS is not defined or equals 0 */
@@ -1307,6 +1359,8 @@ void BPY_pyconstraint_update(Object *owner, bConstraint *con)
data->tarnum = 0;
data->flag &= ~PYCON_USETARGETS;
+ PyGILState_Release(gilstate);
+
return;
}
}
@@ -1335,10 +1389,13 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
bConstraintTarget *ct;
MatrixObject *retmat;
int row, col, index;
-
+ PyGILState_STATE gilstate;
+
if (!con->text) return;
if (con->flag & PYCON_SCRIPTERROR) return;
-
+
+ gilstate = PyGILState_Ensure();
+
globals = CreateGlobalDictionary();
/* wrap blender-data as PyObjects for evaluation
@@ -1357,6 +1414,8 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
if (!setup_armature_weakrefs()) {
fprintf(stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1372,7 +1431,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(tarmats);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1389,7 +1450,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(tarmats);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1408,7 +1471,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(tarmats);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1422,7 +1487,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(tarmats);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1437,7 +1504,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(retval);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1452,7 +1521,9 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
Py_XDECREF(retval);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1471,6 +1542,8 @@ void BPY_pyconstraint_eval(bPythonConstraint *con, bConstraintOb *cob, ListBase
/* clear globals */
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
}
/* This evaluates the target matrix for each target the PyConstraint uses.
@@ -1485,11 +1558,14 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
PyObject *pyargs, *retval;
MatrixObject *retmat;
int row, col;
-
+ PyGILState_STATE gilstate;
+
if (!con->text) return;
if (con->flag & PYCON_SCRIPTERROR) return;
if (!ct) return;
+ gilstate = PyGILState_Ensure();
+
globals = CreateGlobalDictionary();
tar = Object_CreatePyObject(ct->tar);
@@ -1506,6 +1582,7 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
if (!setup_armature_weakrefs()) {
fprintf(stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
return;
}
@@ -1522,7 +1599,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(tarmat);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1539,7 +1618,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(tarmat);
ReleaseGlobalDictionary(globals);
-
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1559,6 +1640,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(tarmat);
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1574,6 +1658,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(tarmat);
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1587,6 +1674,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(retval);
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1602,6 +1692,9 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
Py_XDECREF(retval);
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1621,6 +1714,8 @@ void BPY_pyconstraint_target(bPythonConstraint *con, bConstraintTarget *ct)
/* clear globals */
ReleaseGlobalDictionary(globals);
+
+ PyGILState_Release(gilstate);
}
/* This draws+handles the user-defined interface for editing pyconstraints idprops */
@@ -1631,6 +1726,7 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
PyObject *globals;
PyObject *gval;
PyObject *retval;
+ PyGILState_STATE gilstate;
if (!con->text) return;
if (con->flag & PYCON_SCRIPTERROR) return;
@@ -1648,6 +1744,9 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
/* free temp objects */
Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1661,6 +1760,9 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
/* free temp objects */
ReleaseGlobalDictionary( globals );
Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1673,6 +1775,9 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
ReleaseGlobalDictionary( globals );
Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1683,6 +1788,9 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
/* free temp objects */
ReleaseGlobalDictionary(globals);
Py_XDECREF(idprop);
+
+ PyGILState_Release(gilstate);
+
return;
}
else {
@@ -1692,6 +1800,9 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
/* free temp objects */
Py_XDECREF(idprop);
Py_DECREF(retval);
+
+ PyGILState_Release(gilstate);
+
return;
}
}
@@ -1702,12 +1813,16 @@ void BPY_pyconstraint_settings(void *arg1, void *arg2)
* updates in it reach pydriver evaluation. */
void BPY_pydriver_update(void)
{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
if (bpy_pydriver_Dict) { /* free the global dict used by pydrivers */
PyDict_Clear(bpy_pydriver_Dict);
Py_DECREF(bpy_pydriver_Dict);
bpy_pydriver_Dict = NULL;
}
+ PyGILState_Release(gilstate);
+
return;
}
@@ -1750,15 +1865,19 @@ float BPY_pydriver_eval(IpoDriver *driver)
PyObject *retval, *bpy_ob = NULL;
float result = 0.0f; /* default return */
int setitem_retval;
+ PyGILState_STATE gilstate;
if (!driver) return result;
expr = driver->name; /* the py expression to be evaluated */
if (!expr || expr[0]=='\0') return result;
+ gilstate = PyGILState_Ensure();
+
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
fprintf(stderr, "Pydriver error: couldn't create Python dictionary");
+ PyGILState_Release(gilstate);
return result;
}
}
@@ -1775,6 +1894,7 @@ float BPY_pydriver_eval(IpoDriver *driver)
if( !setup_armature_weakrefs()){
fprintf( stderr, "Oops - weakref dict setup\n");
+ PyGILState_Release(gilstate);
return result;
}
@@ -1782,13 +1902,18 @@ float BPY_pydriver_eval(IpoDriver *driver)
bpy_pydriver_Dict);
if (retval == NULL) {
- return pydriver_error(driver);
+ result = pydriver_error(driver);
+ PyGILState_Release(gilstate);
+ return result;
}
result = ( float )PyFloat_AsDouble( retval );
- if (result == -1 && PyErr_Occurred())
- return pydriver_error(driver);
+ if (result == -1 && PyErr_Occurred()) {
+ result = pydriver_error(driver);
+ PyGILState_Release(gilstate);
+ return result;
+ }
/* remove 'self', since this dict is also used by py buttons */
if (setitem_retval == 0) PyDict_DelItemString(bpy_pydriver_Dict, "self");
@@ -1796,6 +1921,8 @@ float BPY_pydriver_eval(IpoDriver *driver)
/* all fine, make sure the "invalid expression" flag is cleared */
driver->flag &= ~IPO_DRIVER_FLAG_INVALID;
+ PyGILState_Release(gilstate);
+
return result;
}
@@ -1832,15 +1959,20 @@ static int bpy_button_eval_error(char *expr) {
int BPY_button_eval(char *expr, double *value)
{
PyObject *retval, *floatval;
+ PyGILState_STATE gilstate;
+ int ret;
if (!value || !expr || expr[0]=='\0') return -1;
*value = 0.0; /* default value */
+ gilstate = PyGILState_Ensure();
+
if (!bpy_pydriver_Dict) {
if (bpy_pydriver_create_dict() != 0) {
fprintf(stderr,
"Button Python Eval error: couldn't create Python dictionary");
+ PyGILState_Release(gilstate);
return -1;
}
}
@@ -1848,6 +1980,7 @@ int BPY_button_eval(char *expr, double *value)
if( !setup_armature_weakrefs()){
fprintf(stderr, "Oops - weakref dict\n");
+ PyGILState_Release(gilstate);
return -1;
}
@@ -1855,20 +1988,26 @@ int BPY_button_eval(char *expr, double *value)
bpy_pydriver_Dict);
if (retval == NULL) {
- return bpy_button_eval_error(expr);
+ ret = bpy_button_eval_error(expr);
+ PyGILState_Release(gilstate);
+ return ret;
}
else {
floatval = PyNumber_Float(retval);
Py_DECREF(retval);
}
- if (floatval == NULL)
- return bpy_button_eval_error(expr);
- else {
+ if (floatval == NULL) {
+ ret = bpy_button_eval_error(expr);
+ PyGILState_Release(gilstate);
+ return ret;
+ } else {
*value = (float)PyFloat_AsDouble(floatval);
Py_DECREF(floatval);
}
+ PyGILState_Release(gilstate);
+
return 0; /* successful exit */
}
@@ -1973,19 +2112,24 @@ void BPY_do_pyscript( ID * id, short event )
PyObject *dict;
PyObject *ret;
int index, during_slink = during_scriptlink( );
+ PyGILState_STATE gilstate;
/* invalid scriptlinks (new .blend was just loaded), return */
if( during_slink < 0 )
return;
-
+
+ gilstate = PyGILState_Ensure();
+
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict, this is a bug\n");
+ PyGILState_Release(gilstate);
return;
}
value = GetPyObjectFromID( id );
if( !value){
printf("Oops - could not get a valid python object for Blender.link, this is a bug\n");
+ PyGILState_Release(gilstate);
return;
}
@@ -2039,6 +2183,8 @@ void BPY_do_pyscript( ID * id, short event )
PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
PyDict_SetItemString( g_blenderdict, "link", Py_None );
EXPP_dict_set_item_str( g_blenderdict, "event", PyString_FromString( "" ) );
+
+ PyGILState_Release(gilstate);
}
}
@@ -2190,6 +2336,7 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
{
ScriptLink *scriptlink;
int retval = 0;
+ PyGILState_STATE gilstate;
if (!sa || !(G.f & G_DOSCRIPTLINKS)) return 0;
@@ -2213,8 +2360,11 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
disable_where_scriptlink( (short)during_slink );
}
+ gilstate = PyGILState_Ensure();
+
if( !setup_armature_weakrefs()){
printf("Oops - weakref dict, this is a bug\n");
+ PyGILState_Release(gilstate);
return 0;
}
@@ -2290,6 +2440,8 @@ int BPY_do_spacehandlers( ScrArea *sa, unsigned short event,
* space_event is of type DRAW:
* 0 always */
+ PyGILState_Release(gilstate);
+
return retval;
}
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index fc84c9a1445..da8a87ad218 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -672,6 +672,7 @@ void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
uiBlock *block;
char butblock[20];
Script *script = sc->script;
+ PyGILState_STATE gilstate = PyGILState_Ensure();
sprintf( butblock, "win %d", curarea->win );
block = uiNewBlock( &curarea->uiblocks, butblock, UI_EMBOSSX,
@@ -696,6 +697,8 @@ void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
uiDrawBlock( block );
curarea->win_swap = WIN_BACK_OK;
+
+ PyGILState_Release(gilstate);
}
static void spacescript_do_pywin_buttons( SpaceScript * sc,
@@ -709,6 +712,8 @@ static void spacescript_do_pywin_buttons( SpaceScript * sc,
void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
short val, char ascii )
{
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
if( event == QKEY && G.qual & ( LR_ALTKEY | LR_CTRLKEY ) ) {
/* finish script: user pressed ALT+Q or CONTROL+Q */
Script *script = sc->script;
@@ -717,6 +722,8 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
script->flags &= ~SCRIPT_GUI; /* we're done with this script */
+ PyGILState_Release(gilstate);
+
return;
}
@@ -729,6 +736,9 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
* read the comment before check_button_event() below to understand */
if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
+
+ PyGILState_Release(gilstate);
+
return;
}
}
@@ -749,6 +759,8 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
EXPP_dict_set_item_str(g_blenderdict, "event",
PyString_FromString(""));
}
+
+ PyGILState_Release(gilstate);
}
static void exec_but_callback(void *pyobj, void *data)
@@ -869,9 +881,13 @@ void BPy_Free_DrawButtonsList(void)
{
/*Clear the list.*/
if (M_Button_List) {
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
PyList_SetSlice(M_Button_List, 0, PyList_Size(M_Button_List), NULL);
Py_DECREF(M_Button_List);
M_Button_List = NULL;
+
+ PyGILState_Release(gilstate);
}
}
diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c
index 73edcb2df9c..7d346ed9cd9 100644
--- a/source/blender/python/api2_2x/Window.c
+++ b/source/blender/python/api2_2x/Window.c
@@ -1,5 +1,5 @@
/*
- * $Id: Window.c 12813 2007-12-07 09:51:02Z campbellbarton $
+ * $Id$
*
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
*
@@ -512,6 +512,8 @@ static void getSelectedFile( char *name )
pycallback = script->py_browsercallback;
if (pycallback) {
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
result = PyObject_CallFunction( pycallback, "s", name );
if (!result) {
@@ -525,6 +527,8 @@ static void getSelectedFile( char *name )
/* else another call to selector was made inside pycallback */
Py_DECREF(pycallback);
+
+ PyGILState_Release(gilstate);
}
return;