mirror of
https://gitlab.com/splashmapper/splash.git
synced 2026-06-16 12:33:50 +02:00
Improved thread safety in PythonEmbedded
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# This script should be loaded inside a python object of Splash.
|
||||
# To do so, add the following to one of a scene configuration:
|
||||
#
|
||||
# "python" : {
|
||||
# "type" : "python",
|
||||
# "file" : "./httpServer.py"
|
||||
# }
|
||||
#
|
||||
# For this to work, the configuration file should be in the same
|
||||
# directory as this script. Otherwise, modify the path accordingly
|
||||
|
||||
import splash
|
||||
import code
|
||||
import threading
|
||||
|
||||
def repl():
|
||||
import splash
|
||||
global console
|
||||
console = code.InteractiveConsole(locals=locals())
|
||||
console.interact()
|
||||
|
||||
replThread = threading.Thread(target=repl)
|
||||
|
||||
def splash_init():
|
||||
replThread.start()
|
||||
|
||||
def splash_loop():
|
||||
pass
|
||||
|
||||
def splash_stop():
|
||||
print("Press a key to quit")
|
||||
console.push("quit()")
|
||||
pass
|
||||
@@ -74,6 +74,7 @@ class PythonEmbedded : public ControllerObject
|
||||
std::string _filepath {""}; //!< Path to the python script
|
||||
std::string _scriptName {""}; //!< Name of the module (filename minus .py)
|
||||
|
||||
PyThreadState* _pyThreadState {nullptr};
|
||||
bool _doLoop {false}; //!< Set to false to stop the Python loop
|
||||
int _loopDurationMs {5}; //!< Time between loops in ms
|
||||
std::thread _loopThread {}; //!< Python thread loop
|
||||
|
||||
@@ -132,7 +132,6 @@ PyObject* PythonEmbedded::pythonSetGlobal(PyObject* self, PyObject* args)
|
||||
}
|
||||
|
||||
auto value = convertToValue(pyValue).asValues();
|
||||
Py_XDECREF(pyValue);
|
||||
that->setGlobal(string(strName), value);
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
@@ -159,7 +158,6 @@ PyObject* PythonEmbedded::pythonSetObject(PyObject* self, PyObject* args)
|
||||
}
|
||||
|
||||
auto value = convertToValue(pyValue).asValues();
|
||||
Py_XDECREF(pyValue);
|
||||
that->setObject(string(strName), string(strAttr), value);
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
@@ -186,7 +184,6 @@ PyObject* PythonEmbedded::pythonSetObjectsOfType(PyObject* self, PyObject* args)
|
||||
}
|
||||
|
||||
auto value = convertToValue(pyValue).asValues();
|
||||
Py_XDECREF(pyValue);
|
||||
that->setObjectsOfType(string(strType), string(strAttr), value);
|
||||
|
||||
Py_INCREF(Py_True);
|
||||
@@ -325,7 +322,7 @@ bool PythonEmbedded::run()
|
||||
/*************/
|
||||
bool PythonEmbedded::stop()
|
||||
{
|
||||
// Tell // Stop and wait for the loop
|
||||
// Stop and wait for the loop
|
||||
_doLoop = false;
|
||||
if (_loopThread.joinable())
|
||||
_loopThread.join();
|
||||
@@ -346,6 +343,7 @@ void PythonEmbedded::loop()
|
||||
|
||||
// Load the module by its filename
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
|
||||
PyRun_SimpleString("import sys");
|
||||
PyRun_SimpleString(("sys.path.append(\"" + _filepath + "\")").c_str());
|
||||
@@ -369,15 +367,20 @@ void PythonEmbedded::loop()
|
||||
|
||||
auto pFuncLoop = getFuncFromModule(pModule, "splash_loop");
|
||||
auto timerName = "PythonEmbedded_" + _name;
|
||||
|
||||
_pyThreadState = PyEval_SaveThread();
|
||||
while (pFuncLoop && _doLoop)
|
||||
{
|
||||
Timer::get() << timerName;
|
||||
PyEval_RestoreThread(_pyThreadState);
|
||||
PyObject_CallObject(pFuncLoop, nullptr);
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
_pyThreadState = PyEval_SaveThread();
|
||||
Timer::get() >> _loopDurationMs * 1000 >> timerName;
|
||||
}
|
||||
Py_XDECREF(pFuncLoop);
|
||||
PyEval_RestoreThread(_pyThreadState);
|
||||
|
||||
auto pFuncStop = getFuncFromModule(pModule, "splash_stop");
|
||||
if (pFuncStop)
|
||||
@@ -409,7 +412,7 @@ PyObject* PythonEmbedded::getFuncFromModule(PyObject* module, const string& name
|
||||
{
|
||||
if (PyErr_Occurred())
|
||||
PyErr_Print();
|
||||
Log::get() << Log::WARNING << "PythonEmbedded::" << __FUNCTION__ << " - Cannot find function " << _scriptName << Log::endl;
|
||||
Log::get() << Log::WARNING << "PythonEmbedded::" << __FUNCTION__ << " - Cannot find function " << name << Log::endl;
|
||||
}
|
||||
|
||||
return pFunc;
|
||||
|
||||
Reference in New Issue
Block a user