Skip to content
Snippets Groups Projects
Commit bad756cf authored by Joseph Mirabel's avatar Joseph Mirabel Committed by Guilhem Saurel
Browse files

Fix multithreading issues

parent fbb2844a
No related branches found
No related tags found
No related merge requests found
...@@ -62,6 +62,8 @@ namespace dynamicgraph { ...@@ -62,6 +62,8 @@ namespace dynamicgraph {
PyObject* globals(); PyObject* globals();
private: private:
/// The Pythone thread state
PyThreadState *_pyState;
/// Pointer to the dictionary of global variables /// Pointer to the dictionary of global variables
PyObject* globals_; PyObject* globals_;
/// Pointer to the dictionary of local variables /// Pointer to the dictionary of local variables
......
...@@ -139,6 +139,7 @@ Interpreter::Interpreter() ...@@ -139,6 +139,7 @@ Interpreter::Interpreter()
dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL); dlopen(libpython.c_str(), RTLD_LAZY | RTLD_GLOBAL);
#endif #endif
Py_Initialize(); Py_Initialize();
PyEval_InitThreads();
mainmod_ = PyImport_AddModule("__main__"); mainmod_ = PyImport_AddModule("__main__");
Py_INCREF(mainmod_); Py_INCREF(mainmod_);
globals_ = PyModule_GetDict(mainmod_); globals_ = PyModule_GetDict(mainmod_);
...@@ -155,10 +156,14 @@ Interpreter::Interpreter() ...@@ -155,10 +156,14 @@ Interpreter::Interpreter()
(PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception"); (PyModule_GetDict(PyImport_AddModule("traceback")), "format_exception");
assert(PyCallable_Check(traceback_format_exception_)); assert(PyCallable_Check(traceback_format_exception_));
Py_INCREF(traceback_format_exception_); Py_INCREF(traceback_format_exception_);
// Allow threads
_pyState = PyEval_SaveThread();
} }
Interpreter::~Interpreter() Interpreter::~Interpreter()
{ {
PyEval_RestoreThread(_pyState);
//Py_DECREF(mainmod_); //Py_DECREF(mainmod_);
//Py_DECREF(globals_); //Py_DECREF(globals_);
//Py_DECREF(traceback_format_exception_); //Py_DECREF(traceback_format_exception_);
...@@ -180,6 +185,8 @@ void Interpreter::python( const std::string& command, std::string& res, ...@@ -180,6 +185,8 @@ void Interpreter::python( const std::string& command, std::string& res,
out = ""; out = "";
err = ""; err = "";
PyEval_RestoreThread(_pyState);
std::cout << command.c_str() << std::endl; std::cout << command.c_str() << std::endl;
PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_, PyObject* result = PyRun_String(command.c_str(), Py_eval_input, globals_,
globals_); globals_);
...@@ -234,6 +241,9 @@ void Interpreter::python( const std::string& command, std::string& res, ...@@ -234,6 +241,9 @@ void Interpreter::python( const std::string& command, std::string& res,
Py_DecRef(stdout_obj); Py_DecRef(stdout_obj);
Py_DecRef(result2); Py_DecRef(result2);
Py_DecRef(result); Py_DecRef(result);
_pyState = PyEval_SaveThread();
return; return;
} }
...@@ -257,6 +267,8 @@ void Interpreter::runPythonFile( std::string filename, std::string& err) ...@@ -257,6 +267,8 @@ void Interpreter::runPythonFile( std::string filename, std::string& err)
return; return;
} }
PyEval_RestoreThread(_pyState);
err = ""; err = "";
PyObject* pymainContext = globals_; PyObject* pymainContext = globals_;
PyObject* run = PyRun_FileExFlags(pFile, filename.c_str(), PyObject* run = PyRun_FileExFlags(pFile, filename.c_str(),
...@@ -268,12 +280,16 @@ void Interpreter::runPythonFile( std::string filename, std::string& err) ...@@ -268,12 +280,16 @@ void Interpreter::runPythonFile( std::string filename, std::string& err)
std::cerr << err << std::endl;; std::cerr << err << std::endl;;
} }
Py_DecRef(run); Py_DecRef(run);
_pyState = PyEval_SaveThread();
} }
void Interpreter::runMain( void ) void Interpreter::runMain( void )
{ {
const char * argv [] = { "dg-embedded-pysh" }; const char * argv [] = { "dg-embedded-pysh" };
PyEval_RestoreThread(_pyState);
Py_Main(1,const_cast<char**>(argv)); Py_Main(1,const_cast<char**>(argv));
_pyState = PyEval_SaveThread();
} }
std::string Interpreter::processStream(std::istream& stream, std::ostream& os) std::string Interpreter::processStream(std::istream& stream, std::ostream& os)
......
...@@ -72,6 +72,11 @@ namespace dynamicgraph { ...@@ -72,6 +72,11 @@ namespace dynamicgraph {
private: private:
T& call (T& value, Time t) 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"; char format[] = "i";
PyObject* obj = PyObject_CallFunction(callable, format, t); PyObject* obj = PyObject_CallFunction(callable, format, t);
if (obj == NULL) if (obj == NULL)
...@@ -80,6 +85,7 @@ namespace dynamicgraph { ...@@ -80,6 +85,7 @@ namespace dynamicgraph {
signalWrapper::convert (obj, value); signalWrapper::convert (obj, value);
Py_DECREF(obj); Py_DECREF(obj);
} }
PyGILState_Release (gstate);
return value; return value;
} }
PyObject* callable; PyObject* callable;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment