diff --git a/include/dynamic-graph/python/interpreter.hh b/include/dynamic-graph/python/interpreter.hh index 2c49695c5121e62841a16b4d119f4d23ed97ea69..e71168532e7679e6ac64fc59d2385ec2c9b2fdba 100644 --- a/include/dynamic-graph/python/interpreter.hh +++ b/include/dynamic-graph/python/interpreter.hh @@ -62,6 +62,8 @@ namespace dynamicgraph { PyObject* globals(); private: + /// The Pythone thread state + PyThreadState *_pyState; /// Pointer to the dictionary of global variables PyObject* globals_; /// Pointer to the dictionary of local variables diff --git a/src/interpreter.cc b/src/interpreter.cc index 373d5baab27159ac43c7561e2eaaa79a433829bd..b2c4cc8cf564a87134651fb3c9dbcbe8b91763c0 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -139,6 +139,7 @@ Interpreter::Interpreter() dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); #endif Py_Initialize(); + PyEval_InitThreads(); mainmod_ = PyImport_AddModule("__main__"); Py_INCREF(mainmod_); globals_ = PyModule_GetDict(mainmod_); @@ -155,10 +156,14 @@ Interpreter::Interpreter() (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); assert(PyCallable_Check(traceback_format_exception_)); Py_INCREF(traceback_format_exception_); + + // Allow threads + _pyState = PyEval_SaveThread(); } Interpreter::~Interpreter() { + PyEval_RestoreThread(_pyState); //Py_DECREF(mainmod_); //Py_DECREF(globals_); //Py_DECREF(traceback_format_exception_); @@ -180,6 +185,8 @@ void Interpreter::python( const std::string& command, std::string& res, out = ""; err = ""; + PyEval_RestoreThread(_pyState); + std::cout << command.c_str() << std::endl; PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, globals_); @@ -234,6 +241,9 @@ void Interpreter::python( const std::string& command, std::string& res, Py_DecRef(stdout_obj); Py_DecRef(result2); Py_DecRef(result); + + _pyState = PyEval_SaveThread(); + return; } @@ -257,6 +267,8 @@ void Interpreter::runPythonFile( std::string filename, std::string& err) return; } + PyEval_RestoreThread(_pyState); + err = ""; PyObject* pymainContext = globals_; PyObject* run = PyRun_FileExFlags(pFile, filename.c_str(), @@ -268,12 +280,16 @@ void Interpreter::runPythonFile( std::string filename, std::string& err) std::cerr << err << std::endl;; } Py_DecRef(run); + + _pyState = PyEval_SaveThread(); } void Interpreter::runMain( void ) { const char * argv [] = { "dg-embedded-pysh" }; + PyEval_RestoreThread(_pyState); Py_Main(1,const_cast<char**>(argv)); + _pyState = PyEval_SaveThread(); } std::string Interpreter::processStream(std::istream& stream, std::ostream& os) diff --git a/src/signal-wrapper.hh b/src/signal-wrapper.hh index 5f26d02c25b0f6e92e978e56820309bf2fa53cb0..b9572ced9d96eaf568caca5c147106452b53b7c2 100644 --- a/src/signal-wrapper.hh +++ b/src/signal-wrapper.hh @@ -72,6 +72,11 @@ namespace dynamicgraph { private: T& call (T& value, Time t) { + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + if (PyGILState_GetThisThreadState() == NULL) { + dgDEBUG(10) << "python thread not initialized" << std::endl; + } char format[] = "i"; PyObject* obj = PyObject_CallFunction(callable, format, t); if (obj == NULL) @@ -80,6 +85,7 @@ namespace dynamicgraph { signalWrapper::convert (obj, value); Py_DECREF(obj); } + PyGILState_Release (gstate); return value; } PyObject* callable;