+Wed Nov 19 16:15:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
+
+ * include/libvirt/libvirt.h.in: Change semantics of AddHandle
+ to allow for same FD to be registered more than once with
+ varying flags.
+ * qemud/event.c, qemud/event.h, qemud/mdns.c, qemud/qemud.c,
+ qemud/qemud.h, src/domain_conf.h, src/event.c, src/event.h,
+ src/lxc_driver.c, src/qemu_driver.c, src/remote_internal.c:
+ Update to track file handle events via the watch number
+ as per new public API contract
+
Wed Nov 19 15:25:00 GMT 2008 Daniel Berrange <berrange@redhat.com>
Add a callback for freeing the user data for callbacks
int event, int detail, void *opaque);
int myEventAddHandleFunc (int fd, int event,
virEventHandleCallback cb, void *opaque);
-void myEventUpdateHandleFunc(int fd, int event);
-int myEventRemoveHandleFunc(int fd);
+void myEventUpdateHandleFunc(int watch, int event);
+int myEventRemoveHandleFunc(int watch);
int myEventAddTimeoutFunc(int timeout, virEventTimeoutCallback cb,
void *opaque);
}
if(h_cb) {
- h_cb(h_fd,
+ h_cb(0,
+ h_fd,
myPollEventToEventHandleType(pfd.revents & h_event),
h_opaque);
}
mypoll.register(fd, myEventHandleTypeToPollEvent(events))
-def myUpdateHandle(fd, event):
+def myUpdateHandle(watch, event):
global h_fd, h_events
#print "Updating Handle %s %s" % (str(fd), str(events))
h_fd = fd
h_events = event
- mypoll.unregister(fd)
- mypoll.register(fd, myEventHandleTypeToPollEvent(event))
+ mypoll.unregister(watch)
+ mypoll.register(watch, myEventHandleTypeToPollEvent(event))
-def myRemoveHandle(fd):
+def myRemoveHandle(watch):
global h_fd
#print "Removing Handle %s" % str(fd)
h_fd = 0
- mypoll.unregister(fd)
+ mypoll.unregister(watch)
def myAddTimeout(timeout, cb, opaque):
global t_active, t_timeout, t_cb, t_opaque
if h_cb != None:
#print "Invoking Handle CB"
- h_cb(h_fd, myPollEventToEventHandleType(revents & h_events),
+ h_cb(0, h_fd, myPollEventToEventHandleType(revents & h_events),
h_opaque[0], h_opaque[1])
#print "DEBUG EXIT"
/**
* virEventHandleCallback:
*
+ * @watch: watch on which the event occurred
* @fd: file handle on which the event occurred
* @events: bitset of events from virEventHandleType constants
* @opaque: user data registered with handle
*
- * callback for receiving file handle events
+ * Callback for receiving file handle events. The callback will
+ * be invoked once for each event which is pending.
*/
-typedef void (*virEventHandleCallback)(int fd, int events, void *opaque);
+typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque);
/**
* virEventAddHandleFunc:
* @opaque: user data to pass to the callback
*
* Part of the EventImpl, this callback Adds a file handle callback to
- * listen for specific events
+ * listen for specific events. The same file handle can be registered
+ * multiple times provided the requested event sets are non-overlapping
+ *
+ * Returns a handle watch number to be used for updating
+ * and unregistering for events
*/
typedef int (*virEventAddHandleFunc)(int fd, int event,
virEventHandleCallback cb, void *opaque);
/**
* virEventUpdateHandleFunc:
- * @fd: file descriptor to modify
+ * @watch: file descriptor watch to modify
* @event: new events to listen on
*
* Part of the EventImpl, this user-provided callback is notified when
* events to listen on change
*/
-typedef void (*virEventUpdateHandleFunc)(int fd, int event);
+typedef void (*virEventUpdateHandleFunc)(int watch, int event);
/**
* virEventRemoveHandleFunc:
- * @fd: file descriptor to stop listening on
+ * @watch: file descriptor watch to stop listening on
*
* Part of the EventImpl, this user-provided callback is notified when
* an fd is no longer being listened on
*/
-typedef int (*virEventRemoveHandleFunc)(int fd);
+typedef int (*virEventRemoveHandleFunc)(int watch);
/**
* virEventTimeoutCallback:
/**
* virEventHandleCallback:
*
+ * @watch: watch on which the event occurred
* @fd: file handle on which the event occurred
* @events: bitset of events from virEventHandleType constants
* @opaque: user data registered with handle
*
- * callback for receiving file handle events
+ * Callback for receiving file handle events. The callback will
+ * be invoked once for each event which is pending.
*/
-typedef void (*virEventHandleCallback)(int fd, int events, void *opaque);
+typedef void (*virEventHandleCallback)(int watch, int fd, int events, void *opaque);
/**
* virEventAddHandleFunc:
* @opaque: user data to pass to the callback
*
* Part of the EventImpl, this callback Adds a file handle callback to
- * listen for specific events
+ * listen for specific events. The same file handle can be registered
+ * multiple times provided the requested event sets are non-overlapping
+ *
+ * Returns a handle watch number to be used for updating
+ * and unregistering for events
*/
typedef int (*virEventAddHandleFunc)(int fd, int event,
virEventHandleCallback cb, void *opaque);
/**
* virEventUpdateHandleFunc:
- * @fd: file descriptor to modify
+ * @watch: file descriptor watch to modify
* @event: new events to listen on
*
* Part of the EventImpl, this user-provided callback is notified when
* events to listen on change
*/
-typedef void (*virEventUpdateHandleFunc)(int fd, int event);
+typedef void (*virEventUpdateHandleFunc)(int watch, int event);
/**
* virEventRemoveHandleFunc:
- * @fd: file descriptor to stop listening on
+ * @watch: file descriptor watch to stop listening on
*
* Part of the EventImpl, this user-provided callback is notified when
* an fd is no longer being listened on
*/
-typedef int (*virEventRemoveHandleFunc)(int fd);
+typedef int (*virEventRemoveHandleFunc)(int watch);
/**
* virEventTimeoutCallback:
libvirt_virEventInvokeHandleCallback(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args)
{
- int fd, event;
+ int watch, fd, event;
PyObject *py_f;
PyObject *py_opaque;
virEventHandleCallback cb;
void *opaque;
if (!PyArg_ParseTuple
- (args, (char *) "iiOO:virEventInvokeHandleCallback",
- &fd, &event, &py_f, &py_opaque
+ (args, (char *) "iiiOO:virEventInvokeHandleCallback",
+ &watch, &fd, &event, &py_f, &py_opaque
))
return VIR_PY_INT_FAIL;
opaque = (void *) PyvirVoidPtr_Get(py_opaque);
if(cb)
- cb (fd, event, opaque);
+ cb (watch, fd, event, opaque);
return VIR_PY_INT_SUCCESS;
}
/* State for a single file handle being monitored */
struct virEventHandle {
+ int watch;
int fd;
int events;
virEventHandleCallback cb;
/* Only have one event loop */
static struct virEventLoop eventLoop;
+/* Unique ID for the next FD watch to be registered */
+static int nextWatch = 0;
+
/* Unique ID for the next timer to be registered */
static int nextTimer = 0;
eventLoop.handlesAlloc += EVENT_ALLOC_EXTENT;
}
+ eventLoop.handles[eventLoop.handlesCount].watch = nextWatch++;
eventLoop.handles[eventLoop.handlesCount].fd = fd;
eventLoop.handles[eventLoop.handlesCount].events =
virEventHandleTypeToPollEvent(events);
eventLoop.handlesCount++;
- return 0;
+ return nextWatch-1;
}
-void virEventUpdateHandleImpl(int fd, int events) {
+void virEventUpdateHandleImpl(int watch, int events) {
int i;
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
- if (eventLoop.handles[i].fd == fd) {
+ if (eventLoop.handles[i].watch == watch) {
eventLoop.handles[i].events =
virEventHandleTypeToPollEvent(events);
break;
* For this reason we only ever set a flag in the existing list.
* Actual deletion will be done out-of-band
*/
-int virEventRemoveHandleImpl(int fd) {
+int virEventRemoveHandleImpl(int watch) {
int i;
- EVENT_DEBUG("Remove handle %d", fd);
+ EVENT_DEBUG("Remove handle %d", watch);
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
if (eventLoop.handles[i].deleted)
continue;
- if (eventLoop.handles[i].fd == fd) {
- EVENT_DEBUG("mark delete %d", i);
+ if (eventLoop.handles[i].watch == watch) {
+ EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd);
eventLoop.handles[i].deleted = 1;
return 0;
}
if (fds[i].revents) {
hEvents = virPollEventToEventHandleType(fds[i].revents);
- EVENT_DEBUG("Dispatch %d %d %p", fds[i].fd, fds[i].revents,
+ EVENT_DEBUG("Dispatch %d %d %d %p",
+ eventLoop.handles[i].watch,
+ fds[i].fd, fds[i].revents,
eventLoop.handles[i].opaque);
- (eventLoop.handles[i].cb)(fds[i].fd, hEvents,
+ (eventLoop.handles[i].cb)(eventLoop.handles[i].watch,
+ fds[i].fd,
+ hEvents,
eventLoop.handles[i].opaque);
}
}
#ifndef __VIRTD_EVENT_H__
#define __VIRTD_EVENT_H__
-#include "../src/event.h"
+#include "internal.h"
/**
* virEventAddHandleImpl: register a callback for monitoring file handle events
/**
* virEventUpdateHandleImpl: change event set for a monitored file handle
*
- * @fd: file handle to monitor for events
+ * @watch: watch whose handle to update
* @events: bitset of events to watch from POLLnnn constants
*
* Will not fail if fd exists
*/
-void virEventUpdateHandleImpl(int fd, int events);
+void virEventUpdateHandleImpl(int watch, int events);
/**
* virEventRemoveHandleImpl: unregister a callback from a file handle
*
- * @fd: file handle to stop monitoring for events
+ * @watch: watch whose handle to remove
*
* returns -1 if the file handle was not registered, 0 upon success
*/
-int virEventRemoveHandleImpl(int fd);
+int virEventRemoveHandleImpl(int watch);
/**
* virEventAddTimeoutImpl: register a callback for a timer event
/* Avahi API requires this struct names in the app :-( */
struct AvahiWatch {
+ int watch;
int fd;
int revents;
AvahiWatchCallback callback;
}
-static void libvirtd_mdns_watch_dispatch(int fd, int events, void *opaque)
+static void libvirtd_mdns_watch_dispatch(int watch, int fd, int events, void *opaque)
{
AvahiWatch *w = (AvahiWatch*)opaque;
int fd_events = virEventHandleTypeToPollEvent(events);
- AVAHI_DEBUG("Dispatch watch FD %d Event %d", fd, fd_events);
+ AVAHI_DEBUG("Dispatch watch %d FD %d Event %d", watch, fd, fd_events);
w->revents = fd_events;
w->callback(w, fd, fd_events, w->userdata);
}
static AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED,
- int fd, AvahiWatchEvent event, AvahiWatchCallback cb, void *userdata) {
+ int fd, AvahiWatchEvent event,
+ AvahiWatchCallback cb, void *userdata) {
AvahiWatch *w;
virEventHandleType hEvents;
if (VIR_ALLOC(w) < 0)
AVAHI_DEBUG("New handle %p FD %d Event %d", w, w->fd, event);
hEvents = virPollEventToEventHandleType(event);
- if (virEventAddHandleImpl(fd, hEvents,
- libvirtd_mdns_watch_dispatch, w) < 0) {
+ if ((w->watch = virEventAddHandleImpl(fd, hEvents,
+ libvirtd_mdns_watch_dispatch, w)) < 0) {
VIR_FREE(w);
return NULL;
}
static void libvirtd_mdns_watch_update(AvahiWatch *w, AvahiWatchEvent event)
{
AVAHI_DEBUG("Update handle %p FD %d Event %d", w, w->fd, event);
- virEventUpdateHandleImpl(w->fd, event);
+ virEventUpdateHandleImpl(w->watch, event);
}
static AvahiWatchEvent libvirtd_mdns_watch_get_events(AvahiWatch *w)
static void libvirtd_mdns_watch_free(AvahiWatch *w)
{
AVAHI_DEBUG("Free handle %p %d", w, w->fd);
- virEventRemoveHandleImpl(w->fd);
+ virEventRemoveHandleImpl(w->watch);
VIR_FREE(w);
}
errno = origerrno;
}
-static void qemudDispatchClientEvent(int fd, int events, void *opaque);
-static void qemudDispatchServerEvent(int fd, int events, void *opaque);
+static void qemudDispatchClientEvent(int watch, int fd, int events, void *opaque);
+static void qemudDispatchServerEvent(int watch, int fd, int events, void *opaque);
static int qemudRegisterClientEvent(struct qemud_server *server,
struct qemud_client *client,
int removeFirst);
}
static void
-qemudDispatchSignalEvent(int fd ATTRIBUTE_UNUSED,
+qemudDispatchSignalEvent(int watch ATTRIBUTE_UNUSED,
+ int fd ATTRIBUTE_UNUSED,
int events ATTRIBUTE_UNUSED,
void *opaque) {
struct qemud_server *server = (struct qemud_server *)opaque;
goto cleanup;
}
- if (virEventAddHandleImpl(sock->fd,
- VIR_EVENT_HANDLE_READABLE |
- VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- qemudDispatchServerEvent,
- server) < 0) {
+ if ((sock->watch = virEventAddHandleImpl(sock->fd,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ qemudDispatchServerEvent,
+ server)) < 0) {
qemudLog(QEMUD_ERR, "%s",
_("Failed to add server event callback"));
goto cleanup;
goto cleanup;
}
- if (virEventAddHandleImpl(sock->fd,
- VIR_EVENT_HANDLE_READABLE |
- VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- qemudDispatchServerEvent,
- server) < 0) {
+ if ((sock->watch = virEventAddHandleImpl(sock->fd,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ qemudDispatchServerEvent,
+ server)) < 0) {
qemudLog(QEMUD_ERR, "%s", _("Failed to add server event callback"));
goto cleanup;
}
tmp = tmp->next;
}
- virEventRemoveHandleImpl(client->fd);
+ virEventRemoveHandleImpl(client->watch);
/* Deregister event delivery callback */
if(client->conn) {
static void
-qemudDispatchClientEvent(int fd, int events, void *opaque) {
+qemudDispatchClientEvent(int watch, int fd, int events, void *opaque) {
struct qemud_server *server = (struct qemud_server *)opaque;
struct qemud_client *client = server->clients;
while (client) {
- if (client->fd == fd)
+ if (client->watch == watch)
break;
client = client->next;
if (!client)
return;
+ if (client->fd != fd)
+ return;
+
if (events == VIR_EVENT_HANDLE_WRITABLE)
qemudDispatchClientWrite(server, client);
else if (events == VIR_EVENT_HANDLE_READABLE)
}
if (removeFirst)
- if (virEventRemoveHandleImpl(client->fd) < 0)
+ if (virEventRemoveHandleImpl(client->watch) < 0)
return -1;
- if (virEventAddHandleImpl(client->fd,
- mode | VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- qemudDispatchClientEvent,
- server) < 0)
+ if ((client->watch = virEventAddHandleImpl(client->fd,
+ mode | VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ qemudDispatchClientEvent,
+ server)) < 0)
return -1;
return 0;
}
static void
-qemudDispatchServerEvent(int fd, int events, void *opaque) {
+qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
struct qemud_server *server = (struct qemud_server *)opaque;
struct qemud_socket *sock = server->sockets;
while (sock) {
- if (sock->fd == fd)
+ if (sock->watch == watch)
break;
sock = sock->next;
if (!sock)
return;
+ if (sock->fd != fd)
+ return;
+
if (events)
qemudDispatchServer(server, sock);
}
int magic;
int fd;
+ int watch;
int readonly;
enum qemud_mode mode;
struct qemud_socket {
int fd;
+ int watch;
int readonly;
int type; /* qemud_sock_type */
int auth;
struct _virDomainObj {
int stdin_fd;
int stdout_fd;
+ int stdout_watch;
int stderr_fd;
+ int stderr_watch;
int monitor;
+ int monitorWatch;
int logfile;
int pid;
int state;
return addHandleImpl(fd, events, cb, opaque);
}
-void virEventUpdateHandle(int fd, int events) {
- updateHandleImpl(fd, events);
+void virEventUpdateHandle(int watch, int events) {
+ updateHandleImpl(watch, events);
}
-int virEventRemoveHandle(int fd) {
+int virEventRemoveHandle(int watch) {
if (!removeHandleImpl)
return -1;
- return removeHandleImpl(fd);
+ return removeHandleImpl(watch);
}
int virEventAddTimeout(int timeout, virEventTimeoutCallback cb, void *opaque) {
/**
* virEventUpdateHandle: change event set for a monitored file handle
*
- * @fd: file handle to monitor for events
+ * @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 fd, int events);
+void virEventUpdateHandle(int watch, int events);
/**
* virEventRemoveHandle: unregister a callback from a file handle
*
- * @fd: file handle to stop monitoring for events
+ * @watch: watch whose file handle to remove
*
* returns -1 if the file handle was not registered, 0 upon success
*/
-int virEventRemoveHandle(int fd);
+int virEventRemoveHandle(int watch);
/**
* virEventAddTimeout: register a callback for a timer event
DEBUG("container exited with rc: %d", rc);
}
- virEventRemoveHandle(vm->monitor);
+ virEventRemoveHandle(vm->monitorWatch);
close(vm->monitor);
virFileDeletePid(driver->stateDir, vm->def->name);
return lxcVMCleanup(conn, driver, vm);
}
-static void lxcMonitorEvent(int fd,
+static void lxcMonitorEvent(int watch,
+ int fd,
int events ATTRIBUTE_UNUSED,
void *data)
{
unsigned int i;
for (i = 0 ; i < driver->domains.count ; i++) {
- if (driver->domains.objs[i]->monitor == fd) {
+ if (driver->domains.objs[i]->monitorWatch == watch) {
vm = driver->domains.objs[i];
break;
}
}
if (!vm) {
- virEventRemoveHandle(fd);
+ virEventRemoveHandle(watch);
+ return;
+ }
+
+ if (vm->monitor != fd) {
+ virEventRemoveHandle(watch);
return;
}
if (lxcVmTerminate(NULL, driver, vm, SIGINT) < 0)
- virEventRemoveHandle(fd);
+ virEventRemoveHandle(watch);
}
vm->def->id = vm->pid;
vm->state = VIR_DOMAIN_RUNNING;
- if (virEventAddHandle(vm->monitor,
- VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
- lxcMonitorEvent,
- driver) < 0) {
+ if ((vm->monitorWatch = virEventAddHandle(
+ vm->monitor,
+ VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
+ lxcMonitorEvent,
+ driver)) < 0) {
lxcVmTerminate(conn, driver, vm, 0);
goto cleanup;
}
int event,
int detail);
-static void qemudDispatchVMEvent(int fd,
+static void qemudDispatchVMEvent(int watch,
+ int fd,
int events,
void *opaque);
}
if (ret == 0) {
- if ((virEventAddHandle(vm->stdout_fd,
- VIR_EVENT_HANDLE_READABLE |
- VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- qemudDispatchVMEvent,
- driver) < 0) ||
- (virEventAddHandle(vm->stderr_fd,
- VIR_EVENT_HANDLE_READABLE |
- VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- qemudDispatchVMEvent,
- driver) < 0) ||
+ if (((vm->stdout_watch = virEventAddHandle(vm->stdout_fd,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ qemudDispatchVMEvent,
+ driver)) < 0) ||
+ ((vm->stderr_watch = virEventAddHandle(vm->stderr_fd,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ qemudDispatchVMEvent,
+ driver)) < 0) ||
(qemudWaitForMonitor(conn, driver, vm) < 0) ||
(qemudDetectVcpuPIDs(conn, driver, vm) < 0) ||
(qemudInitCpus(conn, driver, vm, migrateFrom) < 0)) {
qemudVMData(driver, vm, vm->stdout_fd);
qemudVMData(driver, vm, vm->stderr_fd);
- virEventRemoveHandle(vm->stdout_fd);
- virEventRemoveHandle(vm->stderr_fd);
+ virEventRemoveHandle(vm->stdout_watch);
+ virEventRemoveHandle(vm->stderr_watch);
if (close(vm->logfile) < 0)
qemudLog(QEMUD_WARN, _("Unable to close logfile %d: %s\n"),
static void
-qemudDispatchVMEvent(int fd, int events, void *opaque) {
+qemudDispatchVMEvent(int watch, int fd, int events, void *opaque) {
struct qemud_driver *driver = (struct qemud_driver *)opaque;
virDomainObjPtr vm = NULL;
unsigned int i;
for (i = 0 ; i < driver->domains.count ; i++) {
if (virDomainIsActive(driver->domains.objs[i]) &&
- (driver->domains.objs[i]->stdout_fd == fd ||
- driver->domains.objs[i]->stderr_fd == fd)) {
+ (driver->domains.objs[i]->stdout_watch == watch ||
+ driver->domains.objs[i]->stderr_watch == watch)) {
vm = driver->domains.objs[i];
break;
}
if (!vm)
return;
+ if (vm->stdout_fd != fd &&
+ vm->stderr_fd != fd) {
+ qemudDispatchVMFailure(driver, vm, fd);
+ return;
+ }
+
if (events == VIR_EVENT_HANDLE_READABLE)
qemudDispatchVMLog(driver, vm, fd);
else
struct private_data {
int magic; /* Should be MAGIC or DEAD. */
int sock; /* Socket. */
+ int watch; /* File handle watch */
pid_t pid; /* PID of tunnel process */
int uses_tls; /* TLS enabled on socket? */
gnutls_session_t session; /* GnuTLS session (if uses_tls != 0). */
static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
-void remoteDomainEventFired(int fd, int event, void *data);
+void remoteDomainEventFired(int watch, int fd, int event, void *data);
static void remoteDomainProcessEvent(virConnectPtr conn, XDR *xdr);
static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr);
void remoteDomainEventQueueFlush(int timer, void *opaque);
DEBUG0("Adding Handler for remote events");
/* Set up a callback to listen on the socket data */
- if (virEventAddHandle(priv->sock,
- VIR_EVENT_HANDLE_READABLE |
- VIR_EVENT_HANDLE_ERROR |
- VIR_EVENT_HANDLE_HANGUP,
- remoteDomainEventFired,
- conn) < 0) {
+ if ((priv->watch = virEventAddHandle(priv->sock,
+ VIR_EVENT_HANDLE_READABLE |
+ VIR_EVENT_HANDLE_ERROR |
+ VIR_EVENT_HANDLE_HANGUP,
+ remoteDomainEventFired,
+ conn)) < 0) {
DEBUG0("virEventAddHandle failed: No addHandleImpl defined."
" continuing without events.");
} else {
* for event data
*/
void
-remoteDomainEventFired(int fd ATTRIBUTE_UNUSED,
+remoteDomainEventFired(int watch,
+ int fd,
int event,
void *opaque)
{
virConnectPtr conn = opaque;
struct private_data *priv = conn->privateData;
- DEBUG("%s : Event fired %d %X", __FUNCTION__, event, event);
+ DEBUG("Event fired %d %d %d %X", watch, fd, event, event);
if (event & (VIR_EVENT_HANDLE_HANGUP | VIR_EVENT_HANDLE_ERROR)) {
DEBUG("%s : VIR_EVENT_HANDLE_HANGUP or "
"VIR_EVENT_HANDLE_ERROR encountered", __FUNCTION__);
- virEventRemoveHandle(fd);
+ virEventRemoveHandle(watch);
return;
}
+ if (fd != priv->sock) {
+ virEventRemoveHandle(watch);
+ return;
+ }
+
/* Read and deserialise length word. */
if (really_read (conn, priv, 0, buffer2, sizeof buffer2) == -1)
return;