[libvirt] [PATCH 0/7 v2] python: Implement missing stream/event ops

Currently it isn't possible to implement the equivalent of 'virsh console' with the python bindings. This series implements the missing functionality required to do so. v2: Pushed first 3 patches Actually export virEvent APIs in libvirt.h DV had comments on patch 1 and patch 6 that I didn't address, if I haven't managed to convince him (or others) with my latest mails I can do another rev of the series. Cole Robinson (7): python: Implement virStreamSend/Recv python: Implement virStreamSend/RecvAll helpers Promote virEvent*Handle/Timeout to public API events: Correct virEventAddTimeout docs python: Add bindings for virEvent*Handle/Timeout python: events: Fix C->Python handle callback prototype python: Mark event callback wrappers as private daemon/libvirtd.c | 1 - daemon/mdns.c | 1 - examples/domain-events/events-python/event-test.py | 6 +- include/libvirt/libvirt.h.in | 14 + python/generator.py | 12 +- python/libvirt-override-virConnect.py | 102 +++---- python/libvirt-override-virStream.py | 101 +++++++- python/libvirt-override.c | 274 +++++++++++++++++--- python/libvirt-override.py | 80 ++++++- python/typewrappers.c | 14 + python/typewrappers.h | 1 + src/conf/domain_event.c | 1 - src/conf/domain_event.h | 1 - src/fdstream.c | 1 - src/libvirt_private.syms | 9 - src/libvirt_public.syms | 6 + src/libxl/libxl_driver.c | 1 - src/lxc/lxc_driver.c | 1 - src/network/bridge_driver.c | 1 - src/node_device/node_device_hal.c | 1 - src/node_device/node_device_udev.c | 1 - src/openvz/openvz_driver.c | 1 - src/qemu/qemu_domain.c | 1 - src/qemu/qemu_driver.c | 1 - src/qemu/qemu_monitor.c | 1 - src/remote/remote_driver.c | 1 - src/test/test_driver.c | 1 - src/uml/uml_driver.c | 1 - src/util/event.c | 56 ++++ src/util/event.h | 73 ------ src/util/util.c | 1 - src/vbox/vbox_tmpl.c | 1 - src/xen/xen_inotify.c | 1 - src/xen/xs_internal.c | 1 - tools/console.c | 1 - 35 files changed, 559 insertions(+), 211 deletions(-) -- 1.7.4.4

The return values for the python version are different that the C version of virStreamSend: on success we return a string, an error raises an exception, and if the stream would block we return int(-2). We need to do this since strings aren't passed by reference in python. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- python/generator.py | 9 +++-- python/libvirt-override-virStream.py | 35 +++++++++++++++++++ python/libvirt-override.c | 62 ++++++++++++++++++++++++++++++++++ python/typewrappers.c | 14 ++++++++ python/typewrappers.h | 1 + 5 files changed, 117 insertions(+), 4 deletions(-) diff --git a/python/generator.py b/python/generator.py index cb4d8a4..315d3d4 100755 --- a/python/generator.py +++ b/python/generator.py @@ -348,8 +348,6 @@ skip_impl = ( 'virNWFilterGetUUID', 'virNWFilterGetUUIDString', 'virNWFilterLookupByUUID', - 'virStreamRecv', - 'virStreamSend', 'virStoragePoolGetUUID', 'virStoragePoolGetUUIDString', 'virStoragePoolLookupByUUID', @@ -393,9 +391,12 @@ skip_function = ( 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError + 'virStreamFree', # Overridden in libvirt-override-virStream.py - 'virStreamRecvAll', - 'virStreamSendAll', + 'virStreamRecvAll', # XXX: Can be written in pure python? + 'virStreamSendAll', # XXX: Can be written in pure python? + 'virStreamRecv', # overridden in libvirt-override-virStream.py + 'virStreamSend', # overridden in libvirt-override-virStream.py # 'Ref' functions have no use for bindings users. "virConnectRef", diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py index 56f1df5..f8a1d0b 100644 --- a/python/libvirt-override-virStream.py +++ b/python/libvirt-override-virStream.py @@ -24,3 +24,38 @@ cbData = {"stream": self, "cb" : cb, "opaque" : opaque} ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData) if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed') + + def recv(self, nbytes): + """Write a series of bytes to the stream. This method may + block the calling application for an arbitrary amount + of time. + + Errors are not guaranteed to be reported synchronously + with the call, but may instead be delayed until a + subsequent call. + + On success, the received data is returned. On failure, an + exception is raised. If the stream is a NONBLOCK stream and + the request would block, integer -2 is returned. + """ + ret = libvirtmod.virStreamRecv(self._o, nbytes) + if ret == None: raise libvirtError ('virStreamRecv() failed') + return ret + + def send(self, data): + """Write a series of bytes to the stream. This method may + block the calling application for an arbitrary amount + of time. Once an application has finished sending data + it should call virStreamFinish to wait for successful + confirmation from the driver, or detect any error + + This method may not be used if a stream source has been + registered + + Errors are not guaranteed to be reported synchronously + with the call, but may instead be delayed until a + subsequent call. + """ + ret = libvirtmod.virStreamSend(self._o, data, len(data)) + if ret == -1: raise libvirtError ('virStreamSend() failed') + return ret diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 55cb61c..63157b4 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -3697,6 +3697,66 @@ libvirt_virStreamEventAddCallback(PyObject *self ATTRIBUTE_UNUSED, return py_retval; } +static PyObject * +libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *pyobj_stream; + virStreamPtr stream; + char *buf = NULL; + int ret; + int nbytes; + + if (!PyArg_ParseTuple(args, (char *) "Oi:virStreamRecv", + &pyobj_stream, &nbytes)) { + DEBUG("%s failed to parse tuple\n", __FUNCTION__); + return VIR_PY_NONE; + } + stream = PyvirStream_Get(pyobj_stream); + + if ((buf = malloc(nbytes+1 > 0 ? nbytes+1 : 1)) == NULL) + return VIR_PY_NONE; + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virStreamRecv(stream, buf, nbytes); + LIBVIRT_END_ALLOW_THREADS; + + buf[ret > -1 ? ret : 0] = '\0'; + DEBUG("StreamRecv ret=%d strlen=%d\n", ret, (int) strlen(buf)); + + if (ret < 0) + return libvirt_intWrap(ret); + return libvirt_charPtrSizeWrap((char *) buf, (Py_ssize_t) ret); +} + +static PyObject * +libvirt_virStreamSend(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *py_retval; + PyObject *pyobj_stream; + virStreamPtr stream; + char *data; + int ret; + int nbytes; + + if (!PyArg_ParseTuple(args, (char *) "Ozi:virStreamRecv", + &pyobj_stream, &data, &nbytes)) { + DEBUG("%s failed to parse tuple\n", __FUNCTION__); + return VIR_PY_INT_FAIL; + } + stream = PyvirStream_Get(pyobj_stream); + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virStreamSend(stream, data, nbytes); + LIBVIRT_END_ALLOW_THREADS; + + DEBUG("StreamSend ret=%d\n", ret); + + py_retval = libvirt_intWrap(ret); + return py_retval; +} + /************************************************************************ * * * The registration stuff * @@ -3715,6 +3775,8 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virConnectDomainEventRegisterAny", libvirt_virConnectDomainEventRegisterAny, METH_VARARGS, NULL}, {(char *) "virConnectDomainEventDeregisterAny", libvirt_virConnectDomainEventDeregisterAny, METH_VARARGS, NULL}, {(char *) "virStreamEventAddCallback", libvirt_virStreamEventAddCallback, METH_VARARGS, NULL}, + {(char *) "virStreamRecv", libvirt_virStreamRecv, METH_VARARGS, NULL}, + {(char *) "virStreamSend", libvirt_virStreamSend, 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.c b/python/typewrappers.c index e39d3cd..b5758b4 100644 --- a/python/typewrappers.c +++ b/python/typewrappers.c @@ -77,6 +77,20 @@ libvirt_ulonglongWrap(unsigned long long val) } PyObject * +libvirt_charPtrSizeWrap(char *str, Py_ssize_t size) +{ + PyObject *ret; + + if (str == NULL) { + Py_INCREF(Py_None); + return (Py_None); + } + ret = PyString_FromStringAndSize(str, size); + free(str); + return (ret); +} + +PyObject * libvirt_charPtrWrap(char *str) { PyObject *ret; diff --git a/python/typewrappers.h b/python/typewrappers.h index cc98110..305d594 100644 --- a/python/typewrappers.h +++ b/python/typewrappers.h @@ -156,6 +156,7 @@ PyObject * libvirt_ulongWrap(unsigned long val); PyObject * libvirt_longlongWrap(long long val); PyObject * libvirt_ulonglongWrap(unsigned long long val); PyObject * libvirt_charPtrWrap(char *str); +PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size); PyObject * libvirt_constcharPtrWrap(const char *str); PyObject * libvirt_charPtrConstWrap(const char *str); PyObject * libvirt_virConnectPtrWrap(virConnectPtr node); -- 1.7.4.4

Pure python implementation. The handler callbacks have been altered a bit compared to the C API: RecvAll doesn't pass length of the data read since that can be trivially obtained from python string objects, and SendAll requires the handler to return the string data to send rather than store the data in a string pointer. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- python/generator.py | 4 +- python/libvirt-override-virStream.py | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/python/generator.py b/python/generator.py index 315d3d4..7c843d7 100755 --- a/python/generator.py +++ b/python/generator.py @@ -393,8 +393,8 @@ skip_function = ( 'virFreeError', # Only needed if we use virSaveLastError 'virStreamFree', # Overridden in libvirt-override-virStream.py - 'virStreamRecvAll', # XXX: Can be written in pure python? - 'virStreamSendAll', # XXX: Can be written in pure python? + 'virStreamRecvAll', # Pure python libvirt-override-virStream.py + 'virStreamSendAll', # Pure python libvirt-override-virStream.py 'virStreamRecv', # overridden in libvirt-override-virStream.py 'virStreamSend', # overridden in libvirt-override-virStream.py diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py index f8a1d0b..82e1648 100644 --- a/python/libvirt-override-virStream.py +++ b/python/libvirt-override-virStream.py @@ -25,6 +25,70 @@ ret = libvirtmod.virStreamEventAddCallback(self._o, events, cbData) if ret == -1: raise libvirtError ('virStreamEventAddCallback() failed') + def recvAll(self, handler, opaque): + """Receive the entire data stream, sending the data to the + requested data sink. This is simply a convenient alternative + to virStreamRecv, for apps that do blocking-I/o. + + A hypothetical handler function looks like: + + def handler(stream, # virStream instance + buf, # string containing received data + opaque): # extra data passed to recvAll as opaque + fd = opaque + return os.write(fd, buf) + """ + while True: + got = self.recv(1024*64) + if got == -2: + raise libvirtError("cannot use recvAll with " + "nonblocking stream") + if len(got) == 0: + break + + try: + ret = handler(self, got, opaque) + if type(ret) is int and ret < 0: + raise RuntimeError("recvAll handler returned %d" % ret) + except Exception, e: + try: + self.abort() + except: + pass + raise e + + def sendAll(self, handler, opaque): + """ + Send the entire data stream, reading the data from the + requested data source. This is simply a convenient alternative + to virStreamSend, for apps that do blocking-I/o. + + A hypothetical handler function looks like: + + def handler(stream, # virStream instance + nbytes, # int amt of data to read + opaque): # extra data passed to recvAll as opaque + fd = opaque + return os.read(fd, nbytes) + """ + while True: + try: + got = handler(self, 1024*64, opaque) + except: + try: + self.abort() + except: + pass + raise e + + if got == "": + break + + ret = self.send(got) + if ret == -2: + raise libvirtError("cannot use recvAll with " + "nonblocking stream") + def recv(self, nbytes): """Write a series of bytes to the stream. This method may block the calling application for an arbitrary amount -- 1.7.4.4

Since we virEventRegisterDefaultImpl is now a public API, callers need a way to invoke the default registered Handle and Timeout functions. We already have general functions for these internally, so promote them to the public API. v2: Actually add APIs to libvirt.h Signed-off-by: Cole Robinson <crobinso@redhat.com> --- daemon/libvirtd.c | 1 - daemon/mdns.c | 1 - include/libvirt/libvirt.h.in | 14 +++++++ python/generator.py | 8 ++++ src/conf/domain_event.c | 1 - src/conf/domain_event.h | 1 - src/fdstream.c | 1 - src/libvirt_private.syms | 9 ---- src/libvirt_public.syms | 6 +++ src/libxl/libxl_driver.c | 1 - src/lxc/lxc_driver.c | 1 - src/network/bridge_driver.c | 1 - src/node_device/node_device_hal.c | 1 - src/node_device/node_device_udev.c | 1 - src/openvz/openvz_driver.c | 1 - src/qemu/qemu_domain.c | 1 - src/qemu/qemu_driver.c | 1 - src/qemu/qemu_monitor.c | 1 - src/remote/remote_driver.c | 1 - src/test/test_driver.c | 1 - src/uml/uml_driver.c | 1 - src/util/event.c | 56 +++++++++++++++++++++++++++ src/util/event.h | 73 ------------------------------------ src/util/util.c | 1 - src/vbox/vbox_tmpl.c | 1 - src/xen/xen_inotify.c | 1 - src/xen/xs_internal.c | 1 - tools/console.c | 1 - 28 files changed, 84 insertions(+), 104 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index bcaa37b..5f291ec 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -62,7 +62,6 @@ #include "uuid.h" #include "remote_driver.h" #include "conf.h" -#include "event.h" #include "event_poll.h" #include "memory.h" #include "stream.h" diff --git a/daemon/mdns.c b/daemon/mdns.c index 03695fd..ca4a433 100644 --- a/daemon/mdns.c +++ b/daemon/mdns.c @@ -39,7 +39,6 @@ #include "libvirtd.h" #include "mdns.h" -#include "event.h" #include "event_poll.h" #include "memory.h" diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index cb9e8ca..3f634e6 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -2166,6 +2166,20 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle, int virEventRegisterDefaultImpl(void); int virEventRunDefaultImpl(void); +int virEventAddHandle(int fd, int events, + virEventHandleCallback cb, + void *opaque, + virFreeCallback ff); +void virEventUpdateHandle(int watch, int events); +int virEventRemoveHandle(int watch); + +int virEventAddTimeout(int frequency, + virEventTimeoutCallback cb, + void *opaque, + virFreeCallback ff); +void virEventUpdateTimeout(int timer, int frequency); +int virEventRemoveTimeout(int timer); + /* * Secret manipulation API */ diff --git a/python/generator.py b/python/generator.py index 7c843d7..6fdc6f8 100755 --- a/python/generator.py +++ b/python/generator.py @@ -398,6 +398,14 @@ skip_function = ( 'virStreamRecv', # overridden in libvirt-override-virStream.py 'virStreamSend', # overridden in libvirt-override-virStream.py + # XXX: Skip for now, some work needed to handle Timeout/Handle callbacks + 'virEventAddHandle', + 'virEventRemoveHandle', + 'virEventUpdateHandle', + 'virEventAddTimeout', + 'virEventRemoveTimeout', + 'virEventUpdateTimeout', + # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c index a1f1b0f..785e9e4 100644 --- a/src/conf/domain_event.c +++ b/src/conf/domain_event.c @@ -24,7 +24,6 @@ #include <config.h> #include "domain_event.h" -#include "event.h" #include "logging.h" #include "datatypes.h" #include "memory.h" diff --git a/src/conf/domain_event.h b/src/conf/domain_event.h index a80868b..ea481b3 100644 --- a/src/conf/domain_event.h +++ b/src/conf/domain_event.h @@ -25,7 +25,6 @@ #ifndef __DOMAIN_EVENT_H__ # define __DOMAIN_EVENT_H__ -# include "event.h" # include "domain_conf.h" typedef struct _virDomainEventCallback virDomainEventCallback; diff --git a/src/fdstream.c b/src/fdstream.c index e19694f..c1ad787 100644 --- a/src/fdstream.c +++ b/src/fdstream.c @@ -38,7 +38,6 @@ #include "datatypes.h" #include "logging.h" #include "memory.h" -#include "event.h" #include "util.h" #include "files.h" #include "configmake.h" diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 03d2ddb..8e844e9 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -455,15 +455,6 @@ ebtablesContextNew; ebtablesRemoveForwardAllowIn; -# event.h -virEventAddHandle; -virEventAddTimeout; -virEventRemoveHandle; -virEventRemoveTimeout; -virEventUpdateHandle; -virEventUpdateTimeout; - - # event_poll.h virEventPollToNativeEvents; virEventPollFromNativeEvents; diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index b2915f6..39d4cae 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -459,6 +459,12 @@ LIBVIRT_0.9.3 { virDomainGetControlInfo; virDomainPinVcpuFlags; virDomainSendKey; + virEventAddHandle; + virEventAddTimeout; + virEventRemoveHandle; + virEventRemoveTimeout; + virEventUpdateHandle; + virEventUpdateTimeout; virNodeGetCPUStats; virNodeGetMemoryStats; } LIBVIRT_0.9.2; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 86ed850..5a5951f 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -38,7 +38,6 @@ #include "datatypes.h" #include "files.h" #include "memory.h" -#include "event.h" #include "uuid.h" #include "command.h" #include "libxl_driver.h" diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 3b0d2a6..d0f7158 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -45,7 +45,6 @@ #include "util.h" #include "bridge.h" #include "veth.h" -#include "event.h" #include "nodeinfo.h" #include "uuid.h" #include "stats_linux.h" diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index 5e4b4d9..4b94959 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -48,7 +48,6 @@ #include "bridge_driver.h" #include "network_conf.h" #include "driver.h" -#include "event.h" #include "buf.h" #include "util.h" #include "command.h" diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index a90e777..27fedc9 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -32,7 +32,6 @@ #include "virterror_internal.h" #include "driver.h" #include "datatypes.h" -#include "event.h" #include "memory.h" #include "uuid.h" #include "logging.h" diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 8b9694e..2d4e078 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -37,7 +37,6 @@ #include "uuid.h" #include "util.h" #include "buf.h" -#include "event.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index 645e426..c13f346 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -49,7 +49,6 @@ #include "virterror_internal.h" #include "datatypes.h" #include "openvz_driver.h" -#include "event.h" #include "buf.h" #include "util.h" #include "openvz_conf.h" diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 06d2a5e..5fe66ac 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -30,7 +30,6 @@ #include "logging.h" #include "virterror_internal.h" #include "c-ctype.h" -#include "event.h" #include "cpu/cpu.h" #include "ignore-value.h" #include "uuid.h" diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 19f22e5..01587e8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -62,7 +62,6 @@ #include "virterror_internal.h" #include "logging.h" #include "datatypes.h" -#include "event.h" #include "buf.h" #include "util.h" #include "nodeinfo.h" diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 1428921..89a3f64 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -32,7 +32,6 @@ #include "qemu_monitor_text.h" #include "qemu_monitor_json.h" #include "qemu_conf.h" -#include "event.h" #include "virterror_internal.h" #include "memory.h" #include "logging.h" diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c index 13f8820..d7ce76e 100644 --- a/src/remote/remote_driver.c +++ b/src/remote/remote_driver.c @@ -80,7 +80,6 @@ #include "qemu_protocol.h" #include "memory.h" #include "util.h" -#include "event.h" #include "ignore-value.h" #include "files.h" #include "command.h" diff --git a/src/test/test_driver.c b/src/test/test_driver.c index f522143..6c8b9cf 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -44,7 +44,6 @@ #include "interface_conf.h" #include "domain_conf.h" #include "domain_event.h" -#include "event.h" #include "storage_conf.h" #include "node_device_conf.h" #include "xml.h" diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index 1d26422..e557fe8 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -47,7 +47,6 @@ #include "uml_driver.h" #include "uml_conf.h" -#include "event.h" #include "buf.h" #include "util.h" #include "nodeinfo.h" diff --git a/src/util/event.c b/src/util/event.c index 11f025b..4108221 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -37,6 +37,16 @@ static virEventAddTimeoutFunc addTimeoutImpl = NULL; static virEventUpdateTimeoutFunc updateTimeoutImpl = NULL; static virEventRemoveTimeoutFunc removeTimeoutImpl = NULL; +/** + * virEventAddHandle: register a callback for monitoring file handle events + * + * @fd: file handle to monitor for events + * @events: bitset of events to watch from virEventHandleType constants + * @cb: callback to invoke when an event occurs + * @opaque: user data to pass to callback + * + * returns -1 if the file handle cannot be registered, 0 upon success + */ int virEventAddHandle(int fd, int events, virEventHandleCallback cb, @@ -48,10 +58,25 @@ int virEventAddHandle(int fd, return addHandleImpl(fd, events, cb, opaque, ff); } +/** + * virEventUpdateHandle: change event set for a monitored file handle + * + * @watch: watch whose file handle to update + * @events: bitset of events to watch from virEventHandleType constants + * + * Will not fail if fd exists + */ void virEventUpdateHandle(int watch, int events) { updateHandleImpl(watch, events); } +/** + * virEventRemoveHandle: unregister a callback from a file handle + * + * @watch: watch whose file handle to remove + * + * returns -1 if the file handle was not registered, 0 upon success + */ int virEventRemoveHandle(int watch) { if (!removeHandleImpl) return -1; @@ -59,6 +84,19 @@ int virEventRemoveHandle(int watch) { return removeHandleImpl(watch); } +/** + * virEventAddTimeout: register a callback for a timer event + * + * @frequency: time between events in milliseconds + * @cb: callback to invoke when an event occurs + * @opaque: user data to pass to callback + * + * Setting frequency to -1 will disable the timer. Setting the frequency + * to zero will cause it to fire on every event loop iteration. + * + * returns -1 if the timer cannot be registered, a positive + * integer timer id upon success + */ int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque, @@ -69,10 +107,28 @@ int virEventAddTimeout(int timeout, return addTimeoutImpl(timeout, cb, opaque, ff); } +/** + * virEventUpdateTimeoutImpl: change frequency for a timer + * + * @timer: timer id to change + * @frequency: time between events in milliseconds + * + * Setting frequency to -1 will disable the timer. Setting the frequency + * to zero will cause it to fire on every event loop iteration. + * + * Will not fail if timer exists + */ void virEventUpdateTimeout(int timer, int timeout) { updateTimeoutImpl(timer, timeout); } +/** + * virEventRemoveTimeout: unregister a callback for a timer + * + * @timer: the timer id to remove + * + * returns -1 if the timer was not registered, 0 upon success + */ int virEventRemoveTimeout(int timer) { if (!removeTimeoutImpl) return -1; diff --git a/src/util/event.h b/src/util/event.h index 68b06c6..2fef314 100644 --- a/src/util/event.h +++ b/src/util/event.h @@ -24,78 +24,5 @@ #ifndef __VIR_EVENT_H__ # define __VIR_EVENT_H__ # include "internal.h" -/** - * virEventAddHandle: register a callback for monitoring file handle events - * - * @fd: file handle to monitor for events - * @events: bitset of events to watch from virEventHandleType constants - * @cb: callback to invoke when an event occurs - * @opaque: user data to pass to callback - * - * returns -1 if the file handle cannot be registered, 0 upon success - */ -int virEventAddHandle(int fd, int events, - virEventHandleCallback cb, - void *opaque, - virFreeCallback ff); - -/** - * virEventUpdateHandle: change event set for a monitored file handle - * - * @watch: watch whose file handle to update - * @events: bitset of events to watch from virEventHandleType constants - * - * Will not fail if fd exists - */ -void virEventUpdateHandle(int watch, int events); - -/** - * virEventRemoveHandle: unregister a callback from a file handle - * - * @watch: watch whose file handle to remove - * - * returns -1 if the file handle was not registered, 0 upon success - */ -int virEventRemoveHandle(int watch); - -/** - * virEventAddTimeout: register a callback for a timer event - * - * @frequency: time between events in milliseconds - * @cb: callback to invoke when an event occurs - * @opaque: user data to pass to callback - * - * Setting frequency to -1 will disable the timer. Setting the frequency - * to zero will cause it to fire on every event loop iteration. - * - * returns -1 if the timer cannot be registered, a positive - * integer timer id upon success - */ -int virEventAddTimeout(int frequency, - virEventTimeoutCallback cb, - void *opaque, - virFreeCallback ff); - -/** - * virEventUpdateTimeoutImpl: change frequency for a timer - * - * @timer: timer id to change - * @frequency: time between events in milliseconds - * - * Setting frequency to -1 will disable the timer. Setting the frequency - * to zero will cause it to fire on every event loop iteration. - * - * Will not fail if timer exists - */ -void virEventUpdateTimeout(int timer, int frequency); - -/** - * virEventRemoveTimeout: unregister a callback for a timer - * - * @timer: the timer id to remove - * - * returns -1 if the timer was not registered, 0 upon success - */ -int virEventRemoveTimeout(int timer); #endif /* __VIR_EVENT_H__ */ diff --git a/src/util/util.c b/src/util/util.c index 8f6d887..463d2b8 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -68,7 +68,6 @@ #include "dirname.h" #include "virterror_internal.h" #include "logging.h" -#include "event.h" #include "buf.h" #include "util.h" #include "memory.h" diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index f2233a5..7fd1200 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -49,7 +49,6 @@ #include "storage_conf.h" #include "storage_file.h" #include "uuid.h" -#include "event.h" #include "memory.h" #include "nodeinfo.h" #include "logging.h" diff --git a/src/xen/xen_inotify.c b/src/xen/xen_inotify.c index 71bb6be..24b4376 100644 --- a/src/xen/xen_inotify.c +++ b/src/xen/xen_inotify.c @@ -31,7 +31,6 @@ #include "datatypes.h" #include "driver.h" #include "memory.h" -#include "event.h" #include "xen_driver.h" #include "conf.h" #include "domain_conf.h" diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c index b684d3d..04bf93a 100644 --- a/src/xen/xs_internal.c +++ b/src/xen/xs_internal.c @@ -29,7 +29,6 @@ #include "datatypes.h" #include "driver.h" #include "memory.h" -#include "event.h" #include "logging.h" #include "uuid.h" #include "xen_driver.h" diff --git a/tools/console.c b/tools/console.c index 0428239..7ca95a3 100644 --- a/tools/console.c +++ b/tools/console.c @@ -43,7 +43,6 @@ # include "memory.h" # include "virterror_internal.h" -# include "event.h" /* ie Ctrl-] as per telnet */ # define CTRL_CLOSE_BRACKET '\35' -- 1.7.4.4

On 06/20/2011 01:34 PM, Cole Robinson wrote:
Since we virEventRegisterDefaultImpl is now a public API, callers need a way to invoke the default registered Handle and Timeout functions. We already have general functions for these internally, so promote them to the public API.
v2: Actually add APIs to libvirt.h
Signed-off-by: Cole Robinson <crobinso@redhat.com> ---
ACK to this change. I'm not confident enough in my python abilities to review the rest of the series, though. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/util/event.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/event.c b/src/util/event.c index 4108221..bd781ec 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -87,11 +87,11 @@ int virEventRemoveHandle(int watch) { /** * virEventAddTimeout: register a callback for a timer event * - * @frequency: time between events in milliseconds + * @timeout: time between events in milliseconds * @cb: callback to invoke when an event occurs * @opaque: user data to pass to callback * - * Setting frequency to -1 will disable the timer. Setting the frequency + * Setting timeout to -1 will disable the timer. Setting the timeout * to zero will cause it to fire on every event loop iteration. * * returns -1 if the timer cannot be registered, a positive -- 1.7.4.4

On 06/20/2011 01:34 PM, Cole Robinson wrote:
Signed-off-by: Cole Robinson <crobinso@redhat.com> --- src/util/event.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
ACK; can be moved earlier in the series if desired. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

Signed-off-by: Cole Robinson <crobinso@redhat.com> --- python/generator.py | 11 +-- python/libvirt-override.c | 192 +++++++++++++++++++++++++++++++++++++------ python/libvirt-override.py | 54 ++++++++++++ 3 files changed, 221 insertions(+), 36 deletions(-) diff --git a/python/generator.py b/python/generator.py index 6fdc6f8..7a04d18 100755 --- a/python/generator.py +++ b/python/generator.py @@ -198,7 +198,8 @@ skipped_types = { 'virConnectDomainEventIOErrorCallback': "No function types in python", 'virConnectDomainEventGraphicsCallback': "No function types in python", 'virStreamEventCallback': "No function types in python", - 'virEventAddHandleFunc': "No function types in python", + 'virEventHandleCallback': "No function types in python", + 'virEventTimeoutCallback': "No function types in python", } ####################################################################### @@ -398,14 +399,6 @@ skip_function = ( 'virStreamRecv', # overridden in libvirt-override-virStream.py 'virStreamSend', # overridden in libvirt-override-virStream.py - # XXX: Skip for now, some work needed to handle Timeout/Handle callbacks - 'virEventAddHandle', - 'virEventRemoveHandle', - 'virEventUpdateHandle', - 'virEventAddTimeout', - 'virEventRemoveTimeout', - 'virEventUpdateTimeout', - # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 63157b4..58d594a 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -61,7 +61,6 @@ static char *py_str(PyObject *obj) return PyString_AsString(str); } - /************************************************************************ * * * Statistics * @@ -2527,6 +2526,30 @@ getLibvirtDomainClassObject (void) { Py_INCREF(libvirt_dom_class); return libvirt_dom_class; } + +static PyObject * +libvirt_lookupPythonFunc(const char *funcname) +{ + PyObject *python_cb; + + /* Lookup the python callback */ + python_cb = PyDict_GetItemString(getLibvirtDictObject(), funcname); + + if (!python_cb) { + DEBUG("%s: Error finding %s\n", __FUNCTION__, funcname); + PyErr_Print(); + PyErr_Clear(); + return NULL; + } + + if (!PyCallable_Check(python_cb)) { + DEBUG("%s: %s is not callable\n", __FUNCTION__, funcname); + return NULL; + } + + return python_cb; +} + /******************************************* * Domain Events *******************************************/ @@ -2712,19 +2735,8 @@ libvirt_virEventAddHandleFunc (int fd, LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ - python_cb = PyDict_GetItemString(getLibvirtDictObject(), - "eventInvokeHandleCallback"); - if(!python_cb) { - DEBUG("%s: Error finding eventInvokeHandleCallback\n", __FUNCTION__); - PyErr_Print(); - PyErr_Clear(); - goto cleanup; - } - if (!PyCallable_Check(python_cb)) { - char *name ATTRIBUTE_UNUSED; - name = py_str(python_cb); - DEBUG("%s: %s is not callable\n", __FUNCTION__, - name ? name : "libvirt.eventInvokeHandleCallback"); + python_cb = libvirt_lookupPythonFunc("eventInvokeHandleCallback"); + if (!python_cb) { goto cleanup; } Py_INCREF(python_cb); @@ -2829,6 +2841,7 @@ libvirt_virEventRemoveHandleFunc(int watch) return retval; } + static int libvirt_virEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb, @@ -2849,19 +2862,8 @@ libvirt_virEventAddTimeoutFunc(int timeout, LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ - python_cb = PyDict_GetItemString(getLibvirtDictObject(), - "eventInvokeTimeoutCallback"); - if(!python_cb) { - DEBUG("%s: Error finding eventInvokeTimeoutCallback\n", __FUNCTION__); - PyErr_Print(); - PyErr_Clear(); - goto cleanup; - } - if (!PyCallable_Check(python_cb)) { - char *name ATTRIBUTE_UNUSED; - name = py_str(python_cb); - DEBUG("%s: %s is not callable\n", __FUNCTION__, - name ? name : "libvirt.eventInvokeTimeoutCallback"); + python_cb = libvirt_lookupPythonFunc("eventInvokeTimeoutCallback"); + if (!python_cb) { goto cleanup; } Py_INCREF(python_cb); @@ -3079,6 +3081,140 @@ libvirt_virEventInvokeTimeoutCallback(PyObject *self ATTRIBUTE_UNUSED, return VIR_PY_INT_SUCCESS; } +static void +libvirt_virEventHandleCallback(int watch, + int fd, + int events, + void *opaque) +{ + PyObject *pyobj_cbData = (PyObject *)opaque; + PyObject *pyobj_ret; + PyObject *python_cb; + + LIBVIRT_ENSURE_THREAD_STATE; + + /* Lookup the python callback */ + python_cb = libvirt_lookupPythonFunc("_dispatchEventHandleCallback"); + if (!python_cb) { + goto cleanup; + } + + Py_INCREF(pyobj_cbData); + + /* Call the pure python dispatcher */ + pyobj_ret = PyObject_CallFunction(python_cb, + (char *)"iiiO", + watch, fd, 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); + } + +cleanup: + LIBVIRT_RELEASE_THREAD_STATE; +} + +static PyObject * +libvirt_virEventAddHandle(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *py_retval; + PyObject *pyobj_cbData; + virEventHandleCallback cb = libvirt_virEventHandleCallback; + int events; + int fd; + int ret; + + if (!PyArg_ParseTuple(args, (char *) "iiO:virEventAddHandle", + &fd, &events, &pyobj_cbData)) { + DEBUG("%s failed to parse tuple\n", __FUNCTION__); + return VIR_PY_INT_FAIL; + } + + Py_INCREF(pyobj_cbData); + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virEventAddHandle(fd, events, cb, pyobj_cbData, NULL); + LIBVIRT_END_ALLOW_THREADS; + + if (ret < 0) { + Py_DECREF(pyobj_cbData); + } + + py_retval = libvirt_intWrap(ret); + return py_retval; +} + +static void +libvirt_virEventTimeoutCallback(int timer, + void *opaque) +{ + PyObject *pyobj_cbData = (PyObject *)opaque; + PyObject *pyobj_ret; + PyObject *python_cb; + + LIBVIRT_ENSURE_THREAD_STATE; + + /* Lookup the python callback */ + python_cb = libvirt_lookupPythonFunc("_dispatchEventTimeoutCallback"); + if (!python_cb) { + goto cleanup; + } + + Py_INCREF(pyobj_cbData); + + /* Call the pure python dispatcher */ + pyobj_ret = PyObject_CallFunction(python_cb, + (char *)"iO", + timer, pyobj_cbData); + + Py_DECREF(pyobj_cbData); + + if (!pyobj_ret) { + DEBUG("%s - ret:%p\n", __FUNCTION__, pyobj_ret); + PyErr_Print(); + } else { + Py_DECREF(pyobj_ret); + } + +cleanup: + LIBVIRT_RELEASE_THREAD_STATE; +} + +static PyObject * +libvirt_virEventAddTimeout(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) +{ + PyObject *py_retval; + PyObject *pyobj_cbData; + virEventTimeoutCallback cb = libvirt_virEventTimeoutCallback; + int timeout; + int ret; + + if (!PyArg_ParseTuple(args, (char *) "iO:virEventAddTimeout", + &timeout, &pyobj_cbData)) { + DEBUG("%s failed to parse tuple\n", __FUNCTION__); + return VIR_PY_INT_FAIL; + } + + Py_INCREF(pyobj_cbData); + + LIBVIRT_BEGIN_ALLOW_THREADS; + ret = virEventAddTimeout(timeout, cb, pyobj_cbData, NULL); + LIBVIRT_END_ALLOW_THREADS; + + if (ret < 0) { + Py_DECREF(pyobj_cbData); + } + + py_retval = libvirt_intWrap(ret); + return py_retval; +} static void libvirt_virConnectDomainEventFreeFunc(void *opaque) @@ -3818,6 +3954,8 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virStoragePoolGetUUIDString", libvirt_virStoragePoolGetUUIDString, METH_VARARGS, NULL}, {(char *) "virStoragePoolLookupByUUID", libvirt_virStoragePoolLookupByUUID, METH_VARARGS, NULL}, {(char *) "virEventRegisterImpl", libvirt_virEventRegisterImpl, METH_VARARGS, NULL}, + {(char *) "virEventAddHandle", libvirt_virEventAddHandle, METH_VARARGS, NULL}, + {(char *) "virEventAddTimeout", libvirt_virEventAddTimeout, METH_VARARGS, NULL}, {(char *) "virEventInvokeHandleCallback", libvirt_virEventInvokeHandleCallback, METH_VARARGS, NULL}, {(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL}, {(char *) "virNodeListDevices", libvirt_virNodeListDevices, METH_VARARGS, NULL}, diff --git a/python/libvirt-override.py b/python/libvirt-override.py index d544a0e..b611ca4 100644 --- a/python/libvirt-override.py +++ b/python/libvirt-override.py @@ -131,3 +131,57 @@ def eventInvokeTimeoutCallback (timer, callback, opaque): Invoke the Event Impl Timeout Callback in C """ libvirtmod.virEventInvokeTimeoutCallback(timer, callback, opaque); + +def _dispatchEventHandleCallback(watch, fd, events, cbData): + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(watch, fd, events, opaque) + return 0 + +def _dispatchEventTimeoutCallback(timer, cbData): + cb = cbData["cb"] + opaque = cbData["opaque"] + + cb(timer, opaque) + return 0 + +def virEventAddHandle(fd, events, cb, opaque): + """ + register a callback for monitoring file handle events + + @fd: file handle to monitor for events + @events: bitset of events to watch from virEventHandleType constants + @cb: callback to invoke when an event occurs + @opaque: user data to pass to callback + + Example callback prototype is: + def cb(watch, # int id of the handle + fd, # int file descriptor the event occured on + events, # int bitmap of events that have occured + opaque): # opaque data passed to eventAddHandle + """ + cbData = {"cb" : cb, "opaque" : opaque} + ret = libvirtmod.virEventAddHandle(fd, events, cbData) + if ret == -1: raise libvirtError ('virEventAddHandle() failed') + return ret + +def virEventAddTimeout(timeout, cb, opaque): + """ + register a callback for a timer event + + @timeout: time between events in milliseconds + @cb: callback to invoke when an event occurs + @opaque: user data to pass to callback + + Setting timeout to -1 will disable the timer. Setting the timeout + to zero will cause it to fire on every event loop iteration. + + Example callback prototype is: + def cb(timer, # int id of the timer + opaque): # opaque data passed to eventAddTimeout + """ + cbData = {"cb" : cb, "opaque" : opaque} + ret = libvirtmod.virEventAddTimeout(timeout, cbData) + if ret == -1: raise libvirtError ('virEventAddTimeout() failed') + return ret -- 1.7.4.4

If registering our own event loop implementation written in python, any handles or timeouts callbacks registered by libvirt C code must be wrapped in a python function. There is some argument trickery that makes this all work, by wrapping the user passed opaque value in a tuple, along with the callback function. Problem is, the current setup requires the user's event loop to know about this trickery, rather than just treating the opaque value as truly opaque. Fix this in a backwards compatible manner, and adjust the example python event loop to do things the proper way. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- examples/domain-events/events-python/event-test.py | 6 +--- python/libvirt-override.py | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/examples/domain-events/events-python/event-test.py b/examples/domain-events/events-python/event-test.py index df75dce..76fda2b 100644 --- a/examples/domain-events/events-python/event-test.py +++ b/examples/domain-events/events-python/event-test.py @@ -66,8 +66,7 @@ class virEventLoopPure: self.cb(self.handle, self.fd, events, - self.opaque[0], - self.opaque[1]) + self.opaque) # This class contains the data we need to track for a # single periodic timer @@ -96,8 +95,7 @@ class virEventLoopPure: def dispatch(self): self.cb(self.timer, - self.opaque[0], - self.opaque[1]) + self.opaque) def __init__(self): diff --git a/python/libvirt-override.py b/python/libvirt-override.py index b611ca4..8df9dc1 100644 --- a/python/libvirt-override.py +++ b/python/libvirt-override.py @@ -117,19 +117,41 @@ def getVersion (name = None): # # Invoke an EventHandle callback # -def eventInvokeHandleCallback (watch, fd, event, callback, opaque): +def eventInvokeHandleCallback(watch, fd, event, opaque, opaquecompat=None): """ Invoke the Event Impl Handle Callback in C """ + # libvirt 0.9.2 and earlier required custom event loops to know + # that opaque=(cb, original_opaque) and pass the values individually + # to this wrapper. This should handle the back compat case, and make + # future invocations match the virEventHandleCallback prototype + if opaquecompat: + callback = opaque + opaque = opaquecompat + else: + callback = opaque[0] + opaque = opaque[1] + libvirtmod.virEventInvokeHandleCallback(watch, fd, event, callback, opaque); # # Invoke an EventTimeout callback # -def eventInvokeTimeoutCallback (timer, callback, opaque): +def eventInvokeTimeoutCallback(timer, opaque, opaquecompat=None): """ Invoke the Event Impl Timeout Callback in C """ + # libvirt 0.9.2 and earlier required custom event loops to know + # that opaque=(cb, original_opaque) and pass the values individually + # to this wrapper. This should handle the back compat case, and make + # future invocations match the virEventTimeoutCallback prototype + if opaquecompat: + callback = opaque + opaque = opaquecompat + else: + callback = opaque[0] + opaque = opaque[1] + libvirtmod.virEventInvokeTimeoutCallback(timer, callback, opaque); def _dispatchEventHandleCallback(watch, fd, events, cbData): -- 1.7.4.4

These functions aren't intended to be called directly by users, so mark them as private. While we're at it, remove unneeded exception handling, and break some long lines. Signed-off-by: Cole Robinson <crobinso@redhat.com> --- python/libvirt-override-virConnect.py | 102 ++++++++++++++------------------- python/libvirt-override-virStream.py | 2 +- python/libvirt-override.c | 24 ++++---- python/libvirt-override.py | 4 +- 4 files changed, 59 insertions(+), 73 deletions(-) diff --git a/python/libvirt-override-virConnect.py b/python/libvirt-override-virConnect.py index 362be75..5be9659 100644 --- a/python/libvirt-override-virConnect.py +++ b/python/libvirt-override-virConnect.py @@ -33,7 +33,7 @@ ret = libvirtmod.virConnectDomainEventRegister(self._o, self) if ret == -1: raise libvirtError ('virConnectDomainEventRegister() failed', conn=self) - def dispatchDomainEventCallbacks(self, dom, event, detail): + def _dispatchDomainEventCallbacks(self, dom, event, detail): """Dispatches events to python user domain event callbacks """ try: @@ -43,7 +43,7 @@ except AttributeError: pass - def dispatchDomainEventLifecycleCallback(self, dom, event, detail, cbData): + def _dispatchDomainEventLifecycleCallback(self, dom, event, detail, cbData): """Dispatches events to python user domain lifecycle event callbacks """ cb = cbData["cb"] @@ -52,89 +52,75 @@ cb(self, virDomain(self, _obj=dom), event, detail, opaque) return 0 - def dispatchDomainEventGenericCallback(self, dom, cbData): + def _dispatchDomainEventGenericCallback(self, dom, cbData): """Dispatches events to python user domain generic event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), opaque) + return 0 - def dispatchDomainEventRTCChangeCallback(self, dom, offset, cbData): + def _dispatchDomainEventRTCChangeCallback(self, dom, offset, cbData): """Dispatches events to python user domain RTC change event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), offset ,opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), offset ,opaque) + return 0 - def dispatchDomainEventWatchdogCallback(self, dom, action, cbData): + def _dispatchDomainEventWatchdogCallback(self, dom, action, cbData): """Dispatches events to python user domain watchdog event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), action, opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), action, opaque) + return 0 - def dispatchDomainEventIOErrorCallback(self, dom, srcPath, devAlias, action, cbData): + def _dispatchDomainEventIOErrorCallback(self, dom, srcPath, devAlias, + action, cbData): """Dispatches events to python user domain IO error event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, opaque) + return 0 - def dispatchDomainEventIOErrorReasonCallback(self, dom, srcPath, devAlias, action, reason, cbData): + def _dispatchDomainEventIOErrorReasonCallback(self, dom, srcPath, + devAlias, action, reason, + cbData): """Dispatches events to python user domain IO error event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, reason, opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), srcPath, devAlias, action, + reason, opaque) + return 0 - def dispatchDomainEventGraphicsCallback(self, dom, phase, localAddr, remoteAddr, authScheme, subject, cbData): + def _dispatchDomainEventGraphicsCallback(self, dom, phase, localAddr, + remoteAddr, authScheme, subject, + cbData): """Dispatches events to python user domain graphics event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), phase, localAddr, remoteAddr, authScheme, subject, opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), phase, localAddr, remoteAddr, + authScheme, subject, opaque) + return 0 - def dispatchDomainEventBlockPullCallback(self, dom, path, status, cbData): + def _dispatchDomainEventBlockPullCallback(self, dom, path, status, cbData): """Dispatches events to python user domain blockPull event callbacks """ - try: - cb = cbData["cb"] - opaque = cbData["opaque"] + cb = cbData["cb"] + opaque = cbData["opaque"] - cb(self, virDomain(self, _obj=dom), path, status, opaque) - return 0 - except AttributeError: - pass + cb(self, virDomain(self, _obj=dom), path, status, opaque) + return 0 def domainEventDeregisterAny(self, callbackID): """Removes a Domain Event Callback. De-registering for a diff --git a/python/libvirt-override-virStream.py b/python/libvirt-override-virStream.py index 82e1648..92e6fb1 100644 --- a/python/libvirt-override-virStream.py +++ b/python/libvirt-override-virStream.py @@ -9,7 +9,7 @@ libvirtmod.virStreamFree(self._o) self._o = None - def dispatchStreamEventCallback(self, events, cbData): + def _dispatchStreamEventCallback(self, events, cbData): """ Dispatches events to python user's stream event callbacks """ diff --git a/python/libvirt-override.c b/python/libvirt-override.c index 58d594a..e7426a5 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -2609,7 +2609,7 @@ libvirt_virConnectDomainEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED, /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn_inst, - (char*)"dispatchDomainEventCallbacks", + (char*)"_dispatchDomainEventCallbacks", (char*)"Oii", pyobj_dom_inst, event, @@ -2735,7 +2735,7 @@ libvirt_virEventAddHandleFunc (int fd, LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ - python_cb = libvirt_lookupPythonFunc("eventInvokeHandleCallback"); + python_cb = libvirt_lookupPythonFunc("_eventInvokeHandleCallback"); if (!python_cb) { goto cleanup; } @@ -2862,7 +2862,7 @@ libvirt_virEventAddTimeoutFunc(int timeout, LIBVIRT_ENSURE_THREAD_STATE; /* Lookup the python callback */ - python_cb = libvirt_lookupPythonFunc("eventInvokeTimeoutCallback"); + python_cb = libvirt_lookupPythonFunc("_eventInvokeTimeoutCallback"); if (!python_cb) { goto cleanup; } @@ -3252,7 +3252,7 @@ libvirt_virConnectDomainEventLifecycleCallback(virConnectPtr conn ATTRIBUTE_UNUS /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventLifecycleCallback", + (char*)"_dispatchDomainEventLifecycleCallback", (char*)"OiiO", pyobj_dom, event, detail, @@ -3298,7 +3298,7 @@ libvirt_virConnectDomainEventGenericCallback(virConnectPtr conn ATTRIBUTE_UNUSED /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventGenericCallback", + (char*)"_dispatchDomainEventGenericCallback", (char*)"OO", pyobj_dom, pyobj_cbData); @@ -3343,7 +3343,7 @@ libvirt_virConnectDomainEventRTCChangeCallback(virConnectPtr conn ATTRIBUTE_UNUS /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventRTCChangeCallback", + (char*)"_dispatchDomainEventRTCChangeCallback", (char*)"OLO", pyobj_dom, (PY_LONG_LONG)utcoffset, @@ -3390,7 +3390,7 @@ libvirt_virConnectDomainEventWatchdogCallback(virConnectPtr conn ATTRIBUTE_UNUSE /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventWatchdogCallback", + (char*)"_dispatchDomainEventWatchdogCallback", (char*)"OiO", pyobj_dom, action, @@ -3439,7 +3439,7 @@ libvirt_virConnectDomainEventIOErrorCallback(virConnectPtr conn ATTRIBUTE_UNUSED /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventIOErrorCallback", + (char*)"_dispatchDomainEventIOErrorCallback", (char*)"OssiO", pyobj_dom, srcPath, devAlias, action, @@ -3489,7 +3489,7 @@ libvirt_virConnectDomainEventIOErrorReasonCallback(virConnectPtr conn ATTRIBUTE_ /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventIOErrorReasonCallback", + (char*)"_dispatchDomainEventIOErrorReasonCallback", (char*)"OssisO", pyobj_dom, srcPath, devAlias, action, reason, @@ -3575,7 +3575,7 @@ libvirt_virConnectDomainEventGraphicsCallback(virConnectPtr conn ATTRIBUTE_UNUSE /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventGraphicsCallback", + (char*)"_dispatchDomainEventGraphicsCallback", (char*)"OiOOsOO", pyobj_dom, phase, pyobj_local, pyobj_remote, @@ -3624,7 +3624,7 @@ libvirt_virConnectDomainEventBlockPullCallback(virConnectPtr conn ATTRIBUTE_UNUS /* Call the Callback Dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_conn, - (char*)"dispatchDomainEventBlockPullCallback", + (char*)"_dispatchDomainEventBlockPullCallback", (char*)"OsiO", pyobj_dom, path, status, pyobj_cbData); @@ -3780,7 +3780,7 @@ libvirt_virStreamEventCallback(virStreamPtr st ATTRIBUTE_UNUSED, /* Call the pure python dispatcher */ pyobj_ret = PyObject_CallMethod(pyobj_stream, - (char *)"dispatchStreamEventCallback", + (char *)"_dispatchStreamEventCallback", (char *)"iO", events, pyobj_cbData); diff --git a/python/libvirt-override.py b/python/libvirt-override.py index 8df9dc1..98241d6 100644 --- a/python/libvirt-override.py +++ b/python/libvirt-override.py @@ -117,7 +117,7 @@ def getVersion (name = None): # # Invoke an EventHandle callback # -def eventInvokeHandleCallback(watch, fd, event, opaque, opaquecompat=None): +def _eventInvokeHandleCallback(watch, fd, event, opaque, opaquecompat=None): """ Invoke the Event Impl Handle Callback in C """ @@ -137,7 +137,7 @@ def eventInvokeHandleCallback(watch, fd, event, opaque, opaquecompat=None): # # Invoke an EventTimeout callback # -def eventInvokeTimeoutCallback(timer, opaque, opaquecompat=None): +def _eventInvokeTimeoutCallback(timer, opaque, opaquecompat=None): """ Invoke the Event Impl Timeout Callback in C """ -- 1.7.4.4
participants (2)
-
Cole Robinson
-
Eric Blake