diff --git a/python/generator.py b/python/generator.py index 2c8fd69d49..cb4d8a4bcb 100755 --- a/python/generator.py +++ b/python/generator.py @@ -197,6 +197,7 @@ skipped_types = { 'virConnectDomainEventWatchdogCallback': "No function types in python", 'virConnectDomainEventIOErrorCallback': "No function types in python", 'virConnectDomainEventGraphicsCallback': "No function types in python", + 'virStreamEventCallback': "No function types in python", 'virEventAddHandleFunc': "No function types in python", } @@ -392,13 +393,11 @@ skip_function = ( 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError - 'virStreamEventAddCallback', + 'virStreamFree', # Overridden in libvirt-override-virStream.py 'virStreamRecvAll', 'virStreamSendAll', - 'virStreamRef', - 'virStreamFree', - # These have no use for bindings users. + # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", "virInterfaceRef", @@ -408,6 +407,7 @@ skip_function = ( "virNWFilterRef", "virStoragePoolRef", "virStorageVolRef", + 'virStreamRef', # This functions shouldn't be called via the bindings (and even the docs # contain an explicit warning to that effect). The equivalent should be diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py index f50a7efe90..56f1df5416 100644 --- a/python/libvirt-override-virStream.py +++ b/python/libvirt-override-virStream.py @@ -9,12 +9,18 @@ libvirtmod.virStreamFree(self._o) self._o = None - def eventAddCallback(self, cb, opaque): - """ """ - try: - self.cb = cb - self.opaque = opaque - ret = libvirtmod.virStreamEventAddCallback(self._o, self) - if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed', conn=self._conn) - except AttributeError: - pass + def dispatchStreamEventCallback(self, events, cbData): + """ + Dispatches events to python user's stream event callbacks + """ + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(self, events, opaque) + return 0 + + def eventAddCallback(self, events, cb, opaque): + self.cb = cb + cbData = {"stream": self, "cb" : cb, "opaque" : opaque} + ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData) + if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed') diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 32b42be861..55cb61ced2 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -3616,6 +3616,86 @@ libvirt_virConnectDomainEventDeregisterAny(ATTRIBUTE_UNUSED PyObject * self, return (py_retval); } +static void +libvirt_virStreamEventFreeFunc(void *opaque) +{ + PyObject *pyobj_stream = (PyObject*)opaque; + LIBVIRT_ENSURE_THREAD_STATE; + Py_DECREF(pyobj_stream); + LIBVIRT_RELEASE_THREAD_STATE; +} + +static void +libvirt_virStreamEventCallback(virStreamPtr st ATTRIBUTE_UNUSED, + int events, + void *opaque) +{ + PyObject *pyobj_cbData = (PyObject *)opaque; + PyObject *pyobj_stream; + PyObject *pyobj_ret; + PyObject *dictKey; + + LIBVIRT_ENSURE_THREAD_STATE; + + Py_INCREF(pyobj_cbData); + dictKey = libvirt_constcharPtrWrap("stream"); + pyobj_stream = PyDict_GetItem(pyobj_cbData, dictKey); + Py_DECREF(dictKey); + + /* Call the pure python dispatcher */ + pyobj_ret = PyObject_CallMethod(pyobj_stream, + (char *)"dispatchStreamEventCallback", + (char *)"iO", + events, pyobj_cbData); + + Py_DECREF(pyobj_cbData); + + if (!pyobj_ret) { + DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); + PyErr_Print(); + } else { + Py_DECREF(pyobj_ret); + } + + LIBVIRT_RELEASE_THREAD_STATE; +} + +static PyObject * +libvirt_virStreamEventAddCallback(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *py_retval; + PyObject *pyobj_stream; + PyObject *pyobj_cbData; + virStreamPtr stream; + virStreamEventCallback cb = libvirt_virStreamEventCallback; + int ret; + int events; + + if (!PyArg_ParseTuple(args, (char *) "OiO:virStreamEventAddCallback", + &pyobj_stream, &events, &pyobj_cbData)) { + DEBUG("%s failed to parse tuple\n", __FUNCTION__); + return VIR_PY_INT_FAIL; + } + + DEBUG("libvirt_virStreamEventAddCallback(%p, %d, %p) called\n", + pyobj_stream, events, pyobj_cbData); + stream = PyvirStream_Get(pyobj_stream); + + Py_INCREF(pyobj_cbData); + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virStreamEventAddCallback(stream, events, cb, pyobj_cbData, + libvirt_virStreamEventFreeFunc); + LIBVIRT_END_ALLOW_THREADS; + + if (ret < 0) { + Py_DECREF(pyobj_cbData); + } + + py_retval = libvirt_intWrap(ret); + return py_retval; +} /************************************************************************ * * @@ -3634,6 +3714,7 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virConnectDomainEventDeregister", libvirt_virConnectDomainEventDeregister, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL}, + {(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL}, {(char *) "virDomainGetInfo", libvirt_virDomainGetInfo, METH_VARARGS, NULL}, {(char *) "virDomainGetState", libvirt_virDomainGetState, METH_VARARGS, NULL}, {(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL}, diff --git a/python/typewrappers.h b/python/typewrappers.h index cb5e5dbaf8..cc981101a2 100644 --- a/python/typewrappers.h +++ b/python/typewrappers.h @@ -150,7 +150,6 @@ typedef struct { void* obj; } PyvirVoidPtr_Object; - PyObject * libvirt_intWrap(int val); PyObject * libvirt_longWrap(long val); PyObject * libvirt_ulongWrap(unsigned long val);