This patch provides an internal driver API to let drivers register event callbacks. It also provides a way for an application using libvirt to provide specific event loop implementations for dealing with these callbacks. Currently this is internal only - no new exported symbols except for a private symbol __virEventRegisterImpl intended for use by the libvirt daemon only. b/src/event.c | 80 ++++++++++++++++++++++++++++++++++++++ b/src/event.h | 100 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/apibuild.py | 2 qemud/driver.c | 3 + qemud/event.c | 8 +-- qemud/event.h | 35 ++++------------ qemud/qemud.c | 48 +++++++++++------------ src/Makefile.am | 1 src/libvirt_sym.version | 2 9 files changed, 225 insertions(+), 54 deletions(-) Dan. -- |=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=| |=- Perl modules: http://search.cpan.org/~danberr/ -=| |=- Projects: http://freshmeat.net/~danielpb/ -=| |=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
diff -r 3de2b940b03d docs/apibuild.py --- a/docs/apibuild.py Thu Jun 21 20:15:56 2007 -0400 +++ b/docs/apibuild.py Thu Jun 21 20:15:57 2007 -0400 @@ -49,6 +49,8 @@ ignored_files = { "conf.c": "internal code", "console.h": "internal code", "console.c": "internal code", + "event.h": "internal code", + "event.c": "internal code", } ignored_words = { diff -r 3de2b940b03d qemud/driver.c --- a/qemud/driver.c Thu Jun 21 20:15:56 2007 -0400 +++ b/qemud/driver.c Thu Jun 21 20:39:34 2007 -0400 @@ -80,6 +80,9 @@ static int qemudSetNonBlock(int fd) { return -1; } + +#define virEventAddHandle(fd, events, cb, opaque) virEventAddHandleImpl(fd, events, cb, opaque) +#define virEventRemoveHandle(fd) virEventRemoveHandleImpl(fd) static void qemudDispatchVMEvent(int fd, int events, void *opaque); diff -r 3de2b940b03d qemud/event.c --- a/qemud/event.c Thu Jun 21 20:15:56 2007 -0400 +++ b/qemud/event.c Thu Jun 21 20:15:57 2007 -0400 @@ -76,7 +76,7 @@ static int nextTimer = 0; * NB, it *must* be safe to call this from within a callback * For this reason we only ever append to existing list. */ -int virEventAddHandle(int fd, int events, virEventHandleCallback cb, void *opaque) { +int virEventAddHandleImpl(int fd, int events, virEventHandleCallback cb, void *opaque) { qemudDebug("Add handle %d %d %p %p\n", fd, events, cb, opaque); if (eventLoop.handlesCount == eventLoop.handlesAlloc) { struct virEventHandle *tmp; @@ -109,7 +109,7 @@ int virEventAddHandle(int fd, int events * For this reason we only ever set a flag in the existing list. * Actual deletion will be done out-of-band */ -int virEventRemoveHandle(int fd) { +int virEventRemoveHandleImpl(int fd) { int i; qemudDebug("Remove handle %d\n", fd); for (i = 0 ; i < eventLoop.handlesCount ; i++) { @@ -131,7 +131,7 @@ int virEventRemoveHandle(int fd) { * NB, it *must* be safe to call this from within a callback * For this reason we only ever append to existing list. */ -int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque) { +int virEventAddTimeoutImpl(int timeout, virEventTimeoutCallback cb, void *opaque) { struct timeval tv; qemudDebug("Adding timeout with %d ms period", timeout); if (gettimeofday(&tv, NULL) < 0) { @@ -173,7 +173,7 @@ int virEventAddTimeout(int timeout, virE * For this reason we only ever set a flag in the existing list. * Actual deletion will be done out-of-band */ -int virEventRemoveTimeout(int timer) { +int virEventRemoveTimeoutImpl(int timer) { int i; for (i = 0 ; i < eventLoop.timeoutsCount ; i++) { if (eventLoop.timeouts[i].deleted) diff -r 3de2b940b03d qemud/event.h --- a/qemud/event.h Thu Jun 21 20:15:56 2007 -0400 +++ b/qemud/event.h Thu Jun 21 20:39:05 2007 -0400 @@ -24,18 +24,10 @@ #ifndef __VIRTD_EVENT_H__ #define __VIRTD_EVENT_H__ +#include "../src/event.h" /** - * virEventHandleCallback: callback for receiving file handle events - * - * @fd: file handle on which the event occured - * @events: bitset of events from POLLnnn constants - * @opaque: user data registered with handle - */ -typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); - -/** - * virEventAddHandle: register a callback for monitoring file handle events + * virEventAddHandleImpl: register a callback for monitoring file handle events * * @fd: file handle to monitor for events * @events: bitset of events to wach from POLLnnn constants @@ -44,27 +36,19 @@ typedef void (*virEventHandleCallback)(i * * returns -1 if the file handle cannot be registered, 0 upon success */ -int virEventAddHandle(int fd, int events, virEventHandleCallback cb, void *opaque); +int virEventAddHandleImpl(int fd, int events, virEventHandleCallback cb, void *opaque); /** - * virEventRemoveHandle: unregister a callback from a file handle + * virEventRemoveHandleImpl: unregister a callback from a file handle * * @fd: file handle to stop monitoring for events * * returns -1 if the file handle was not registered, 0 upon success */ -int virEventRemoveHandle(int fd); +int virEventRemoveHandleImpl(int fd); /** - * virEventTimeoutCallback: callback for receiving timer events - * - * @timer: timer id emitting the event - * @opaque: user data registered with handle - */ -typedef void (*virEventTimeoutCallback)(int timer, void *opaque); - -/** - * virEventAddTimeout: register a callback for a timer event + * virEventAddTimeoutImpl: register a callback for a timer event * * @timeout: timeout between events in milliseconds * @cb: callback to invoke when an event occurrs @@ -73,17 +57,16 @@ typedef void (*virEventTimeoutCallback)( * returns -1 if the file handle cannot be registered, a positive * integer timer id upon success */ -int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque); +int virEventAddTimeoutImpl(int timeout, virEventTimeoutCallback cb, void *opaque); /** - * virEventRemoveTimeout: unregister a callback for a timer + * virEventRemoveTimeoutImpl: 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); - +int virEventRemoveTimeoutImpl(int timer); /** * virEventRunOnce: run a single iteration of the event loop. diff -r 3de2b940b03d qemud/qemud.c --- a/qemud/qemud.c Thu Jun 21 20:15:56 2007 -0400 +++ b/qemud/qemud.c Thu Jun 21 20:38:57 2007 -0400 @@ -471,10 +471,10 @@ static int qemudListenUnix(struct qemud_ goto cleanup; } - if (virEventAddHandle(sock->fd, - POLLIN| POLLERR | POLLHUP, - qemudDispatchServerEvent, - server) < 0) { + if (virEventAddHandleImpl(sock->fd, + POLLIN| POLLERR | POLLHUP, + qemudDispatchServerEvent, + server) < 0) { qemudLog(QEMUD_ERR, "Failed to add server event callback"); goto cleanup; } @@ -584,10 +584,10 @@ remoteListenTCP (struct qemud_server *se return -1; } - if (virEventAddHandle(sock->fd, - POLLIN| POLLERR | POLLHUP, - qemudDispatchServerEvent, - server) < 0) { + if (virEventAddHandleImpl(sock->fd, + POLLIN| POLLERR | POLLHUP, + qemudDispatchServerEvent, + server) < 0) { qemudLog(QEMUD_ERR, "Failed to add server event callback"); return -1; } @@ -1056,7 +1056,7 @@ static void qemudDispatchClientFailure(s tmp = tmp->next; } - virEventRemoveHandle(client->fd); + virEventRemoveHandleImpl(client->fd); if (client->tls && client->session) gnutls_deinit (client->session); close(client->fd); @@ -1418,22 +1418,22 @@ static int qemudRegisterClientEvent(stru struct qemud_client *client, int removeFirst) { if (removeFirst) - if (virEventRemoveHandle(client->fd) < 0) + if (virEventRemoveHandleImpl(client->fd) < 0) return -1; if (client->tls) { - if (virEventAddHandle(client->fd, - (client->direction ? - POLLOUT : POLLIN) | POLLERR | POLLHUP, - qemudDispatchClientEvent, - server) < 0) + if (virEventAddHandleImpl(client->fd, + (client->direction ? + POLLOUT : POLLIN) | POLLERR | POLLHUP, + qemudDispatchClientEvent, + server) < 0) return -1; } else { - if (virEventAddHandle(client->fd, - (client->mode == QEMUD_MODE_TX_PACKET ? - POLLOUT : POLLIN) | POLLERR | POLLHUP, - qemudDispatchClientEvent, - server) < 0) + if (virEventAddHandleImpl(client->fd, + (client->mode == QEMUD_MODE_TX_PACKET ? + POLLOUT : POLLIN) | POLLERR | POLLHUP, + qemudDispatchClientEvent, + server) < 0) return -1; } @@ -1864,10 +1864,10 @@ int main(int argc, char **argv) { goto error2; } - if (virEventAddHandle(sigpipe[0], - POLLIN, - qemudDispatchSignalEvent, - server) < 0) { + if (virEventAddHandleImpl(sigpipe[0], + POLLIN, + qemudDispatchSignalEvent, + server) < 0) { qemudLog(QEMUD_ERR, "Failed to register callback for signal pipe"); ret = 3; goto error2; diff -r 3de2b940b03d src/Makefile.am --- a/src/Makefile.am Thu Jun 21 20:15:56 2007 -0400 +++ b/src/Makefile.am Thu Jun 21 20:25:07 2007 -0400 @@ -31,6 +31,7 @@ CLIENT_SOURCES = \ test.c test.h \ buf.c buf.h \ xml.c xml.h \ + event.c event.h \ xen_unified.c xen_unified.h \ xen_internal.c xen_internal.h \ xs_internal.c xs_internal.h \ diff -r 3de2b940b03d src/event.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/event.c Thu Jun 21 20:25:07 2007 -0400 @@ -0,0 +1,80 @@ +/* + * event.h: event loop for monitoring file handles + * + * Copyright (C) 2007 Daniel P. Berrange + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Daniel P. Berrange <berrange@xxxxxxxxxx> + */ + + +#include "event.h" + +#include <stdlib.h> + +static virEventAddHandleFunc addHandleImpl = NULL; +static virEventRemoveHandleFunc removeHandleImpl = NULL; +static virEventAddTimeoutFunc addTimeoutImpl = NULL; +static virEventRemoveTimeoutFunc removeTimeoutImpl = NULL; + +int virEventAddHandle(int fd, int events, virEventHandleCallback cb, void *opaque) { + if (!addHandleImpl) + return -1; + + return addHandleImpl(fd, events, cb, opaque); +} + +int virEventRemoveHandle(int fd) { + if (!removeHandleImpl) + return -1; + + return removeHandleImpl(fd); +} + +int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque) { + if (!addTimeoutImpl) + return -1; + + return addTimeoutImpl(timeout, cb, opaque); +} + +int virEventRemoveTimeout(int timer) { + if (!removeTimeoutImpl) + return -1; + + return removeTimeoutImpl(timer); +} + +void __virEventRegisterImpl(virEventAddHandleFunc addHandle, + virEventRemoveHandleFunc removeHandle, + virEventAddTimeoutFunc addTimeout, + virEventRemoveTimeoutFunc removeTimeout) { + addHandleImpl = addHandle; + removeHandleImpl = removeHandle; + addTimeoutImpl = addTimeout; + removeTimeoutImpl = removeTimeout; +} + + +/* + * Local variables: + * indent-tabs-mode: nil + * c-indent-level: 4 + * c-basic-offset: 4 + * tab-width: 4 + * End: + */ diff -r 3de2b940b03d src/event.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/event.h Thu Jun 21 20:15:57 2007 -0400 @@ -0,0 +1,100 @@ +/* + * event.h: event loop for monitoring file handles + * + * Copyright (C) 2007 Daniel P. Berrange + * Copyright (C) 2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Daniel P. Berrange <berrange@xxxxxxxxxx> + */ + +#ifndef __VIR_EVENT_H__ +#define __VIR_EVENT_H__ + + +/** + * virEventHandleCallback: callback for receiving file handle events + * + * @fd: file handle on which the event occured + * @events: bitset of events from POLLnnn constants + * @opaque: user data registered with handle + */ +typedef void (*virEventHandleCallback)(int fd, int events, void *opaque); + +/** + * virEventAddHandle: register a callback for monitoring file handle events + * + * @fd: file handle to monitor for events + * @events: bitset of events to wach from POLLnnn constants + * @cb: callback to invoke when an event occurrs + * @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); + +/** + * virEventRemoveHandle: unregister a callback from a file handle + * + * @fd: file handle to stop monitoring for events + * + * returns -1 if the file handle was not registered, 0 upon success + */ +int virEventRemoveHandle(int fd); + +/** + * virEventTimeoutCallback: callback for receiving timer events + * + * @timer: timer id emitting the event + * @opaque: user data registered with handle + */ +typedef void (*virEventTimeoutCallback)(int timer, void *opaque); + +/** + * virEventAddTimeout: register a callback for a timer event + * + * @timeout: timeout between events in milliseconds + * @cb: callback to invoke when an event occurrs + * @opaque: user data to pass to callback + * + * returns -1 if the file handle cannot be registered, a positive + * integer timer id upon success + */ +int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque); + +/** + * 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); + +typedef int (*virEventAddHandleFunc)(int, int, virEventHandleCallback, void *); +typedef int (*virEventRemoveHandleFunc)(int); + +typedef int (*virEventAddTimeoutFunc)(int, virEventTimeoutCallback, void *); +typedef int (*virEventRemoveTimeoutFunc)(int); + +void __virEventRegisterImpl(virEventAddHandleFunc addHandle, + virEventRemoveHandleFunc removeHandle, + virEventAddTimeoutFunc addTimeout, + virEventRemoveTimeoutFunc removeTimeout); + +#define virEventRegisterImpl(ah,rh,at,rt) __virEventRegisterImpl(ah,rh,at,rt) + +#endif /* __VIR_EVENT_H__ */ diff -r 3de2b940b03d src/libvirt_sym.version --- a/src/libvirt_sym.version Thu Jun 21 20:15:56 2007 -0400 +++ b/src/libvirt_sym.version Thu Jun 21 20:35:34 2007 -0400 @@ -99,5 +99,7 @@ __virGetDomain; __virGetNetwork; + __virEventRegisterImpl; + local: *; };