fix issues in teardown.
This commit is contained in:
parent
d4889b5b78
commit
16c4fa3345
@ -21,6 +21,7 @@ typedef struct {
|
|||||||
|
|
||||||
static int PyNymeaLoggingHandler_init(PyNymeaLoggingHandler *self, PyObject *args, PyObject */*kwds*/)
|
static int PyNymeaLoggingHandler_init(PyNymeaLoggingHandler *self, PyObject *args, PyObject */*kwds*/)
|
||||||
{
|
{
|
||||||
|
qCDebug(dcPythonIntegrations()) << "+++ PyNymeaLoggingHandler";
|
||||||
char *category = nullptr;
|
char *category = nullptr;
|
||||||
if (!PyArg_ParseTuple(args, "s", &category)) {
|
if (!PyArg_ParseTuple(args, "s", &category)) {
|
||||||
qCWarning(dcPythonIntegrations()) << "PyNymeaLoggingHandler: Error parsing parameters";
|
qCWarning(dcPythonIntegrations()) << "PyNymeaLoggingHandler: Error parsing parameters";
|
||||||
@ -35,11 +36,11 @@ static int PyNymeaLoggingHandler_init(PyNymeaLoggingHandler *self, PyObject *arg
|
|||||||
|
|
||||||
static void PyNymeaLoggingHandler_dealloc(PyNymeaLoggingHandler * self)
|
static void PyNymeaLoggingHandler_dealloc(PyNymeaLoggingHandler * self)
|
||||||
{
|
{
|
||||||
|
qCDebug(dcPythonIntegrations()) << "--- PyNymeaLoggingHandler";
|
||||||
free(self->category);
|
free(self->category);
|
||||||
Py_TYPE(self)->tp_free(self);
|
Py_TYPE(self)->tp_free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject * PyNymeaLoggingHandler_log(PyNymeaLoggingHandler* self, PyObject* args)
|
static PyObject * PyNymeaLoggingHandler_log(PyNymeaLoggingHandler* self, PyObject* args)
|
||||||
{
|
{
|
||||||
QStringList strings;
|
QStringList strings;
|
||||||
|
|||||||
@ -67,7 +67,6 @@ static PyTypeObject PyParamType = {
|
|||||||
sizeof(PyParam), /* tp_basicsize */
|
sizeof(PyParam), /* tp_basicsize */
|
||||||
0, /* tp_itemsize */
|
0, /* tp_itemsize */
|
||||||
(destructor)PyParam_dealloc,/* tp_dealloc */
|
(destructor)PyParam_dealloc,/* tp_dealloc */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyParam* PyParam_fromParam(const Param ¶m)
|
static PyParam* PyParam_fromParam(const Param ¶m)
|
||||||
|
|||||||
@ -212,7 +212,6 @@ PythonIntegrationPlugin::~PythonIntegrationPlugin()
|
|||||||
|
|
||||||
s_plugins.take(this);
|
s_plugins.take(this);
|
||||||
Py_XDECREF(m_pluginModule);
|
Py_XDECREF(m_pluginModule);
|
||||||
Py_XDECREF(m_logger);
|
|
||||||
Py_DECREF(m_nymeaModule);
|
Py_DECREF(m_nymeaModule);
|
||||||
|
|
||||||
Py_EndInterpreter(m_threadState);
|
Py_EndInterpreter(m_threadState);
|
||||||
@ -223,19 +222,33 @@ PythonIntegrationPlugin::~PythonIntegrationPlugin()
|
|||||||
|
|
||||||
void PythonIntegrationPlugin::initPython()
|
void PythonIntegrationPlugin::initPython()
|
||||||
{
|
{
|
||||||
Q_ASSERT_X(s_mainThreadState == nullptr, "PythonIntegrationPlugin::initPython()", "initPython() must be called exactly once.");
|
Q_ASSERT_X(s_mainThreadState == nullptr, "PythonIntegrationPlugin::initPython()", "initPython() must be called exactly once before calling deinitPython().");
|
||||||
|
|
||||||
PyImport_AppendInittab("nymea", PyInit_nymea);
|
// Only modify the init tab once (initPython() might be called again after calling deinitPython())
|
||||||
|
static bool initTabPrepared = false;
|
||||||
|
if (!initTabPrepared) {
|
||||||
|
PyImport_AppendInittab("nymea", PyInit_nymea);
|
||||||
|
initTabPrepared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the python engine and fire up threading support
|
||||||
Py_InitializeEx(0);
|
Py_InitializeEx(0);
|
||||||
PyEval_InitThreads();
|
PyEval_InitThreads();
|
||||||
|
|
||||||
// Store the main thread state and release the GIL
|
// Store the main thread state and release the GIL
|
||||||
s_mainThreadState = PyEval_SaveThread();
|
s_mainThreadState = PyEval_SaveThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonIntegrationPlugin::deinitPython()
|
void PythonIntegrationPlugin::deinitPython()
|
||||||
{
|
{
|
||||||
|
// Restore our main thread state
|
||||||
PyEval_RestoreThread(s_mainThreadState);
|
PyEval_RestoreThread(s_mainThreadState);
|
||||||
Py_Finalize();
|
|
||||||
|
// Tear down the python engine
|
||||||
|
Py_FinalizeEx();
|
||||||
|
|
||||||
|
// Our main thread state is destroyed now
|
||||||
|
s_mainThreadState = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
||||||
@ -244,18 +257,18 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
|||||||
|
|
||||||
QFile metaDataFile(fi.absolutePath() + "/" + fi.baseName() + ".json");
|
QFile metaDataFile(fi.absolutePath() + "/" + fi.baseName() + ".json");
|
||||||
if (!metaDataFile.open(QFile::ReadOnly)) {
|
if (!metaDataFile.open(QFile::ReadOnly)) {
|
||||||
qCWarning(dcThingManager()) << "Error opening metadata file:" << metaDataFile.fileName();
|
qCWarning(dcPythonIntegrations()) << "Error opening metadata file:" << metaDataFile.fileName();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
QJsonParseError error;
|
QJsonParseError error;
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(metaDataFile.readAll(), &error);
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(metaDataFile.readAll(), &error);
|
||||||
if (error.error != QJsonParseError::NoError) {
|
if (error.error != QJsonParseError::NoError) {
|
||||||
qCWarning(dcThingManager()) << "Error parsing metadata file:" << error.errorString();
|
qCWarning(dcPythonIntegrations()) << "Error parsing metadata file:" << error.errorString();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setMetaData(PluginMetadata(jsonDoc.object()));
|
setMetaData(PluginMetadata(jsonDoc.object()));
|
||||||
if (!metadata().isValid()) {
|
if (!metadata().isValid()) {
|
||||||
qCWarning(dcThingManager()) << "Plugin metadata not valid for plugin:" << scriptFile;
|
qCWarning(dcPythonIntegrations()) << "Plugin metadata not valid for plugin:" << scriptFile;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,8 +327,11 @@ bool PythonIntegrationPlugin::loadScript(const QString &scriptFile)
|
|||||||
PyObject *args = Py_BuildValue("(s)", category.toUtf8().data());
|
PyObject *args = Py_BuildValue("(s)", category.toUtf8().data());
|
||||||
PyNymeaLoggingHandler *logger = reinterpret_cast<PyNymeaLoggingHandler*>(PyObject_CallObject((PyObject*)&PyNymeaLoggingHandlerType, args));
|
PyNymeaLoggingHandler *logger = reinterpret_cast<PyNymeaLoggingHandler*>(PyObject_CallObject((PyObject*)&PyNymeaLoggingHandlerType, args));
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
PyModule_AddObject(m_pluginModule, "logger", reinterpret_cast<PyObject*>(logger));
|
int loggerAdded = PyModule_AddObject(m_pluginModule, "logger", reinterpret_cast<PyObject*>(logger));
|
||||||
m_logger = (PyObject*)logger;
|
if (loggerAdded != 0) {
|
||||||
|
qCWarning(dcPythonIntegrations()) << "Failed to add the logger object";
|
||||||
|
Py_DECREF(logger);
|
||||||
|
}
|
||||||
|
|
||||||
// Export metadata ids into module
|
// Export metadata ids into module
|
||||||
exportIds();
|
exportIds();
|
||||||
|
|||||||
@ -76,8 +76,6 @@ private:
|
|||||||
// The imported plugin module (the plugin.py)
|
// The imported plugin module (the plugin.py)
|
||||||
PyObject *m_pluginModule = nullptr;
|
PyObject *m_pluginModule = nullptr;
|
||||||
|
|
||||||
PyObject *m_logger = nullptr;
|
|
||||||
|
|
||||||
// A map of plugin instances to plugin python scripts/modules
|
// A map of plugin instances to plugin python scripts/modules
|
||||||
// Make sure to hold the GIL when accessing this.
|
// Make sure to hold the GIL when accessing this.
|
||||||
static QHash<PythonIntegrationPlugin*, PyObject*> s_plugins;
|
static QHash<PythonIntegrationPlugin*, PyObject*> s_plugins;
|
||||||
|
|||||||
@ -161,6 +161,7 @@ void TestIntegrations::initTestCase()
|
|||||||
"Tests.debug=true\n"
|
"Tests.debug=true\n"
|
||||||
"Mock.debug=true\n"
|
"Mock.debug=true\n"
|
||||||
"Translations.debug=true\n"
|
"Translations.debug=true\n"
|
||||||
|
"PythonIntegrations.debug=true\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Adding an async mock to be used in tests below
|
// Adding an async mock to be used in tests below
|
||||||
|
|||||||
@ -414,7 +414,9 @@ void NymeaTestBase::waitForDBSync()
|
|||||||
void NymeaTestBase::restartServer()
|
void NymeaTestBase::restartServer()
|
||||||
{
|
{
|
||||||
// Destroy and recreate the core instance...
|
// Destroy and recreate the core instance...
|
||||||
|
qCDebug(dcTests()) << "Tearing down server instance";
|
||||||
NymeaCore::instance()->destroy();
|
NymeaCore::instance()->destroy();
|
||||||
|
qCDebug(dcTests()) << "Restarting server instance";
|
||||||
NymeaCore::instance()->init();
|
NymeaCore::instance()->init();
|
||||||
QSignalSpy coreSpy(NymeaCore::instance(), SIGNAL(initialized()));
|
QSignalSpy coreSpy(NymeaCore::instance(), SIGNAL(initialized()));
|
||||||
coreSpy.wait();
|
coreSpy.wait();
|
||||||
|
|||||||
Reference in New Issue
Block a user