some fixes
This commit is contained in:
parent
8aa91292fe
commit
1ce5d5980d
@ -44,6 +44,7 @@ static PyObject* PyThing_new(PyTypeObject *type, PyObject */*args*/, PyObject */
|
|||||||
if (self == NULL) {
|
if (self == NULL) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
qWarning() << "*creating pyThing" << self;
|
||||||
self->mutex = new QMutex();
|
self->mutex = new QMutex();
|
||||||
|
|
||||||
return (PyObject*)self;
|
return (PyObject*)self;
|
||||||
@ -86,6 +87,7 @@ static void PyThing_setThing(PyThing *self, Thing *thing)
|
|||||||
|
|
||||||
|
|
||||||
static void PyThing_dealloc(PyThing * self) {
|
static void PyThing_dealloc(PyThing * self) {
|
||||||
|
qWarning() << "destryoing pything" << self;
|
||||||
Py_XDECREF(self->name);
|
Py_XDECREF(self->name);
|
||||||
Py_XDECREF(self->id);
|
Py_XDECREF(self->id);
|
||||||
Py_XDECREF(self->thingClassId);
|
Py_XDECREF(self->thingClassId);
|
||||||
@ -213,7 +215,6 @@ static PyMethodDef PyThing_methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static PyMemberDef PyThing_members[] = {
|
static PyMemberDef PyThing_members[] = {
|
||||||
{"nameChangedHandler", T_OBJECT_EX, offsetof(PyThing, nameChangedHandler), READONLY, "Set a callback for when the thing name changes"},
|
|
||||||
{"nameChangedHandler", T_OBJECT_EX, offsetof(PyThing, nameChangedHandler), 0, "Set a callback for when the thing name changes"},
|
{"nameChangedHandler", T_OBJECT_EX, offsetof(PyThing, nameChangedHandler), 0, "Set a callback for when the thing name changes"},
|
||||||
{nullptr, 0, 0, 0, nullptr} /* Sentinel */
|
{nullptr, 0, 0, 0, nullptr} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|||||||
@ -43,8 +43,9 @@ PyObject* nymea_flush(PyObject* /*self*/, PyObject* /*args*/)
|
|||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* task_done(PyObject* /*self*/, PyObject* args)
|
PyObject* PythonIntegrationPlugin::task_done(PyObject* self, PyObject* args)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(self)
|
||||||
|
|
||||||
PyObject *result = nullptr;
|
PyObject *result = nullptr;
|
||||||
|
|
||||||
@ -63,8 +64,9 @@ PyObject* task_done(PyObject* /*self*/, PyObject* args)
|
|||||||
Py_XDECREF(repr);
|
Py_XDECREF(repr);
|
||||||
Py_XDECREF(str);
|
Py_XDECREF(str);
|
||||||
|
|
||||||
qCWarning(dcThingManager()) << "Exception:" << bytes;
|
qCWarning(dcThingManager()) << "Exception in plugin:" << bytes;
|
||||||
|
|
||||||
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
@ -75,7 +77,7 @@ static PyMethodDef nymea_methods[] =
|
|||||||
{
|
{
|
||||||
{"write", nymea_write, METH_VARARGS, "write to stdout through qDebug()"},
|
{"write", nymea_write, METH_VARARGS, "write to stdout through qDebug()"},
|
||||||
{"flush", nymea_flush, METH_VARARGS, "flush stdout (no-op)"},
|
{"flush", nymea_flush, METH_VARARGS, "flush stdout (no-op)"},
|
||||||
{"task_done", task_done, METH_VARARGS, "callback to clean up after asyc coroutines"},
|
{"task_done", PythonIntegrationPlugin::task_done, METH_VARARGS, "callback to clean up after asyc coroutines"},
|
||||||
{nullptr, nullptr, 0, nullptr} // sentinel
|
{nullptr, nullptr, 0, nullptr} // sentinel
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,7 +183,9 @@ PyObject *PythonIntegrationPlugin::pyMyThings(PyObject *self, PyObject */*args*/
|
|||||||
PyObject* result = PyTuple_New(plugin->m_things.count());
|
PyObject* result = PyTuple_New(plugin->m_things.count());
|
||||||
for (int i = 0; i < plugin->m_things.count(); i++) {
|
for (int i = 0; i < plugin->m_things.count(); i++) {
|
||||||
Thing *thing = plugin->m_things.keys().at(i);
|
Thing *thing = plugin->m_things.keys().at(i);
|
||||||
PyTuple_SET_ITEM(result, i, (PyObject*)plugin->m_things.value(thing));
|
PyThing *pyThing = plugin->m_things.value(thing);
|
||||||
|
Py_INCREF(pyThing);
|
||||||
|
PyTuple_SET_ITEM(result, i, (PyObject*)pyThing);
|
||||||
}
|
}
|
||||||
plugin->m_mutex.unlock();
|
plugin->m_mutex.unlock();
|
||||||
return result;
|
return result;
|
||||||
@ -395,6 +399,7 @@ void PythonIntegrationPlugin::setupThing(ThingSetupInfo *info)
|
|||||||
PyThingSetupInfo *pyInfo = (PyThingSetupInfo*)PyObject_CallObject((PyObject*)&PyThingSetupInfoType, NULL);
|
PyThingSetupInfo *pyInfo = (PyThingSetupInfo*)PyObject_CallObject((PyObject*)&PyThingSetupInfoType, NULL);
|
||||||
pyInfo->info = info;
|
pyInfo->info = info;
|
||||||
pyInfo->pyThing = pyThing;
|
pyInfo->pyThing = pyThing;
|
||||||
|
Py_INCREF(pyThing);
|
||||||
|
|
||||||
m_things.insert(info->thing(), pyThing);
|
m_things.insert(info->thing(), pyThing);
|
||||||
|
|
||||||
@ -572,7 +577,7 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
|||||||
{
|
{
|
||||||
PyGILState_STATE s = PyGILState_Ensure();
|
PyGILState_STATE s = PyGILState_Ensure();
|
||||||
|
|
||||||
qCDebug(dcThingManager()) << "Calling python plugin function" << function;
|
qCDebug(dcThingManager()) << "Calling python plugin function" << function << "on plugin" << s_plugins.key(m_module)->pluginName();
|
||||||
PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8());
|
PyObject *pFunc = PyObject_GetAttrString(m_module, function.toUtf8());
|
||||||
if(!pFunc || !PyCallable_Check(pFunc)) {
|
if(!pFunc || !PyCallable_Check(pFunc)) {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
@ -643,9 +648,10 @@ bool PythonIntegrationPlugin::callPluginFunction(const QString &function, PyObje
|
|||||||
void PythonIntegrationPlugin::cleanupPyThing(PyThing *pyThing)
|
void PythonIntegrationPlugin::cleanupPyThing(PyThing *pyThing)
|
||||||
{
|
{
|
||||||
// It could happen that the python thread is currently holding the mutex
|
// It could happen that the python thread is currently holding the mutex
|
||||||
// whike waiting on a blocking queued connection on the thing (e.g. PyThing_name).
|
// on the thing (e.g. PyThing_name).
|
||||||
// We'd deadlock if we wait for the mutex forever here. So let's process events
|
// We'd deadlock if we wait for the mutex forever here. So let's process events
|
||||||
// while waiting for it...
|
// while waiting for it...
|
||||||
|
qWarning() << "Locking cleanup";
|
||||||
while (!pyThing->mutex->tryLock()) {
|
while (!pyThing->mutex->tryLock()) {
|
||||||
qApp->processEvents(QEventLoop::EventLoopExec);
|
qApp->processEvents(QEventLoop::EventLoopExec);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,6 +41,10 @@ public:
|
|||||||
static PyObject* pyMyThings(PyObject *self, PyObject* args);
|
static PyObject* pyMyThings(PyObject *self, PyObject* args);
|
||||||
static PyObject* pyAutoThingsAppeared(PyObject *self, PyObject* args);
|
static PyObject* pyAutoThingsAppeared(PyObject *self, PyObject* args);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// python callbacks
|
||||||
|
static PyObject* task_done(PyObject* self, PyObject* args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void exportIds();
|
void exportIds();
|
||||||
void exportThingClass(const ThingClass &thingClass);
|
void exportThingClass(const ThingClass &thingClass);
|
||||||
|
|||||||
@ -21,9 +21,11 @@ def startMonitoringAutoThings():
|
|||||||
logger.log("Creating new auto thing")
|
logger.log("Creating new auto thing")
|
||||||
descriptor = nymea.ThingDescriptor(pyMockAutoThingClassId, "Python Mock auto thing")
|
descriptor = nymea.ThingDescriptor(pyMockAutoThingClassId, "Python Mock auto thing")
|
||||||
autoThingsAppeared([descriptor])
|
autoThingsAppeared([descriptor])
|
||||||
|
logger.log("Done start monitoring auto things")
|
||||||
|
|
||||||
|
|
||||||
async def setupThing(info):
|
async def setupThing(info):
|
||||||
|
logger.log("setupThing for", info.thing.name)
|
||||||
info.finish(nymea.ThingErrorNoError)
|
info.finish(nymea.ThingErrorNoError)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user