Signed-off-by: Cole Robinson <crobinso(a)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 745828b..2777c61 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",
}
#######################################################################
@@ -396,14 +397,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 388c937..b000718 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -59,7 +59,6 @@ static char *py_str(PyObject *obj)
return PyString_AsString(str);
}
-
/************************************************************************
* *
* Statistics *
@@ -2499,6 +2498,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
*******************************************/
@@ -2684,19 +2707,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);
@@ -2801,6 +2813,7 @@ libvirt_virEventRemoveHandleFunc(int watch)
return retval;
}
+
static int
libvirt_virEventAddTimeoutFunc(int timeout,
virEventTimeoutCallback cb,
@@ -2821,19 +2834,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);
@@ -3051,6 +3053,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)
@@ -3789,6 +3925,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