mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-06 17:17:56 +03:00
python: Add bindings for virEvent*Handle/Timeout
This commit is contained in:
parent
27e47955a0
commit
d0e3f3d6a6
@ -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",
|
||||
|
@ -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},
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user