Commit: d050577176366617bcfdc86f9dd659143e024648
Author: Mitchell Stokes
Date:   Wed Apr 16 01:15:40 2014 -0700
https://developer.blender.org/rBd050577176366617bcfdc86f9dd659143e024648

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.

===================================================================

M       source/gameengine/Converter/BL_BlenderDataConversion.cpp
M       source/gameengine/Converter/KX_ConvertControllers.cpp
M       source/gameengine/Converter/KX_ConvertControllers.h
M       source/gameengine/Ketsji/KX_Scene.cpp

===================================================================

diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp 
b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
index b283330..f03f4a9 100644
--- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp
+++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp
@@ -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++)
        {
diff --git a/source/gameengine/Converter/KX_ConvertControllers.cpp 
b/source/gameengine/Converter/KX_ConvertControllers.cpp
index 5d3d0f3..ab5f161 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.cpp
+++ b/source/gameengine/Converter/KX_ConvertControllers.cpp
@@ -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
diff --git a/source/gameengine/Converter/KX_ConvertControllers.h 
b/source/gameengine/Converter/KX_ConvertControllers.h
index 817a49e..babe3e2 100644
--- a/source/gameengine/Converter/KX_ConvertControllers.h
+++ b/source/gameengine/Converter/KX_ConvertControllers.h
@@ -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__ */
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp 
b/source/gameengine/Ketsji/KX_Scene.cpp
index 2e56029..64ba17f 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -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

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to