Fix T39445: Async LibLoad Crash

There was some deadlock due to trying manage Python's GIL. Instead of
continuing to fight with it, anything needing to call into Python while
conversion during lib loading is just delayed until it can be done in
the main thread.
This commit is contained in:
Mitchell Stokes
2014-04-16 01:15:40 -07:00
parent 4769b44bdd
commit d050577176
4 changed files with 24 additions and 10 deletions

View File

@@ -2874,7 +2874,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
struct Object* blenderobj = gameobj->GetBlenderObject();
int layerMask = (groupobj.find(blenderobj) == groupobj.end()) ? activeLayerBitInfo : 0;
bool isInActiveLayer = (blenderobj->lay & layerMask)!=0;
BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter);
BL_ConvertControllers(blenderobj,gameobj,logicmgr, layerMask,isInActiveLayer,converter, libloading);
}
for ( i=0;i<logicbrick_conversionlist->GetCount();i++)
{

View File

@@ -94,7 +94,8 @@ void BL_ConvertControllers(
SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
KX_BlenderSceneConverter* converter
KX_BlenderSceneConverter* converter,
bool libloading
) {
int uniqueint=0;
int count = 0;
@@ -157,8 +158,9 @@ void BL_ConvertControllers(
SCA_PythonController* pyctrl = new SCA_PythonController(gameobj, pycont->mode);
gamecontroller = pyctrl;
#ifdef WITH_PYTHON
PyGILState_STATE gstate = PyGILState_Ensure();
pyctrl->SetNamespace(converter->GetPyNamespace());
// When libloading, this is delayed to KX_Scene::MergeScene_LogicBrick to avoid GIL issues
if (!libloading)
pyctrl->SetNamespace(converter->GetPyNamespace());
if (pycont->mode==SCA_PythonController::SCA_PYEXEC_SCRIPT) {
if (pycont->text)
@@ -185,8 +187,6 @@ void BL_ConvertControllers(
pyctrl->SetDebug(true);
}
}
PyGILState_Release(gstate);
#endif // WITH_PYTHON
break;
@@ -219,8 +219,8 @@ void BL_ConvertControllers(
converter->RegisterGameController(gamecontroller, bcontr);
#ifdef WITH_PYTHON
PyGILState_STATE gstate = PyGILState_Ensure();
if (bcontr->type==CONT_PYTHON) {
// When libloading, this is delayed to KX_Scene::MergeScene_LogicBrick to avoid GIL issues
if (!libloading && bcontr->type==CONT_PYTHON) {
SCA_PythonController *pyctrl= static_cast<SCA_PythonController*>(gamecontroller);
/* not strictly needed but gives syntax errors early on and
* gives more predictable performance for larger scripts */
@@ -235,7 +235,6 @@ void BL_ConvertControllers(
}
}
PyGILState_Release(gstate);
#endif // WITH_PYTHON
//done with gamecontroller

View File

@@ -40,7 +40,8 @@ void BL_ConvertControllers(
class SCA_LogicManager* logicmgr,
int activeLayerBitInfo,
bool isInActiveLayer,
class KX_BlenderSceneConverter* converter
class KX_BlenderSceneConverter* converter,
bool libloading
);
#endif /* __KX_CONVERTCONTROLLERS_H__ */

View File

@@ -49,6 +49,7 @@
//#include "SCA_RandomEventManager.h"
//#include "KX_RayEventManager.h"
#include "SCA_2DFilterActuator.h"
#include "SCA_PythonController.h"
#include "KX_TouchEventManager.h"
#include "SCA_KeyboardManager.h"
#include "SCA_MouseManager.h"
@@ -1900,6 +1901,19 @@ static void MergeScene_LogicBrick(SCA_ILogicBrick* brick, KX_Scene *to)
if (filter_actuator) {
filter_actuator->SetScene(to);
}
#ifdef WITH_PYTHON
// Python must be called from the main thread unless we want to deal
// with GIL issues. So, this is delayed until here in case of async
// libload (originally in KX_ConvertControllers)
SCA_PythonController *pyctrl = dynamic_cast<SCA_PythonController*>(brick);
if (pyctrl) {
pyctrl->SetNamespace(KX_GetActiveEngine()->GetPyNamespace());
if (pyctrl->m_mode==SCA_PythonController::SCA_PYEXEC_SCRIPT)
pyctrl->Compile();
}
#endif
}
#ifdef WITH_BULLET