1
0
mirror of https://gitlab.com/libvirt/libvirt-python.git synced 2025-08-02 04:21:59 +03:00

Fix use of virDomainEventRegister in python bindings

If an app used the virDomainEventRegister binding instead
of the virDomainEventRegisterAny binding, it would never
have its callback invoked. This is because the code for
dispatching from the C libvirt_virConnectDomainEventCallback
method was totally fubar.

If DEBUG macro was set in the python build the error would
become visible

  "libvirt_virConnectDomainEventCallback dom_class is not a class!"

The code in libvirt_virConnectDomainEventCallback was
inexplicably complex and has apparently never worked. The
fix is to write it the same way as the other callback handlers.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange
2013-12-03 15:24:17 +00:00
parent 9d9e2513c0
commit 7f842365b1
2 changed files with 6 additions and 60 deletions

View File

@ -38,7 +38,7 @@
"""
try:
for cb,opaque in self.domainEventCallbacks.items():
cb(self,dom,event,detail,opaque)
cb(self, virDomain(self, _obj=dom), event, detail, opaque)
return 0
except AttributeError:
pass

View File

@ -4923,7 +4923,6 @@ cleanup:
*******************************************/
static PyObject *libvirt_module = NULL;
static PyObject *libvirt_dict = NULL;
static PyObject *libvirt_dom_class = NULL;
static PyObject *
getLibvirtModuleObject(void) {
@ -4959,23 +4958,6 @@ getLibvirtDictObject(void) {
return libvirt_dict;
}
static PyObject *
getLibvirtDomainClassObject(void) {
if (libvirt_dom_class)
return libvirt_dom_class;
// PyDict_GetItemString returns a borrowed reference
libvirt_dom_class = PyDict_GetItemString(getLibvirtDictObject(),
"virDomain");
if (!libvirt_dom_class) {
DEBUG("%s Error importing virDomain class\n", __FUNCTION__);
PyErr_Print();
return NULL;
}
Py_INCREF(libvirt_dom_class);
return libvirt_dom_class;
}
static PyObject *
libvirt_lookupPythonFunc(const char *funcname)
@ -5013,13 +4995,9 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
{
PyObject *pyobj_ret;
PyObject *pyobj_conn_inst = (PyObject*)opaque;
PyObject *pyobj_conn = (PyObject*)opaque;
PyObject *pyobj_dom;
PyObject *pyobj_dom_args;
PyObject *pyobj_dom_inst;
PyObject *dom_class;
int ret = -1;
LIBVIRT_ENSURE_THREAD_STATE;
@ -5027,45 +5005,15 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
/* Create a python instance of this virDomainPtr */
virDomainRef(dom);
pyobj_dom = libvirt_virDomainPtrWrap(dom);
pyobj_dom_args = PyTuple_New(2);
if (PyTuple_SetItem(pyobj_dom_args, 0, pyobj_conn_inst) != 0) {
DEBUG("%s error creating tuple", __FUNCTION__);
goto cleanup;
}
if (PyTuple_SetItem(pyobj_dom_args, 1, pyobj_dom) != 0) {
DEBUG("%s error creating tuple", __FUNCTION__);
goto cleanup;
}
Py_INCREF(pyobj_conn_inst);
dom_class = getLibvirtDomainClassObject();
if (!PyClass_Check(dom_class)) {
DEBUG("%s dom_class is not a class!\n", __FUNCTION__);
goto cleanup;
}
pyobj_dom_inst = PyInstance_New(dom_class,
pyobj_dom_args,
NULL);
Py_DECREF(pyobj_dom_args);
if (!pyobj_dom_inst) {
DEBUG("%s Error creating a python instance of virDomain\n",
__FUNCTION__);
PyErr_Print();
goto cleanup;
}
/* Call the Callback Dispatcher */
pyobj_ret = PyObject_CallMethod(pyobj_conn_inst,
pyobj_ret = PyObject_CallMethod(pyobj_conn,
(char*)"_dispatchDomainEventCallbacks",
(char*)"Oii",
pyobj_dom_inst,
event,
detail);
pyobj_dom,
event, detail);
Py_DECREF(pyobj_dom_inst);
Py_DECREF(pyobj_dom);
if (!pyobj_ret) {
DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret);
@ -5075,8 +5023,6 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
ret = 0;
}
cleanup:
LIBVIRT_RELEASE_THREAD_STATE;
return ret;
}