|
Mark McLoughlin |
a6e23d |
From 6483ee77ed12f037d68a6adc690624fa1b508dc0 Mon Sep 17 00:00:00 2001
|
|
Mark McLoughlin |
a6e23d |
From: Daniel P. Berrange <berrange@redhat.com>
|
|
Mark McLoughlin |
a6e23d |
Date: Tue, 12 May 2009 16:43:04 +0000
|
|
Mark McLoughlin |
a6e23d |
Subject: [PATCH 2/2] Fix watch/timer event deletion
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
---
|
|
Mark McLoughlin |
a6e23d |
qemud/event.c | 112 ++++++++++++++++++++++++++-------------------------------
|
|
Mark McLoughlin |
a6e23d |
1 files changed, 51 insertions(+), 61 deletions(-)
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
diff --git a/qemud/event.c b/qemud/event.c
|
|
Mark McLoughlin |
a6e23d |
index 754f2b1..a57d967 100644
|
|
Mark McLoughlin |
a6e23d |
--- a/qemud/event.c
|
|
Mark McLoughlin |
a6e23d |
+++ b/qemud/event.c
|
|
Mark McLoughlin |
a6e23d |
@@ -313,7 +313,7 @@ static int virEventCalculateTimeout(int *timeout) {
|
|
Mark McLoughlin |
a6e23d |
EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount);
|
|
Mark McLoughlin |
a6e23d |
/* Figure out if we need a timeout */
|
|
Mark McLoughlin |
a6e23d |
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
|
Mark McLoughlin |
a6e23d |
- if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0)
|
|
Mark McLoughlin |
a6e23d |
+ if (eventLoop.timeouts[i].frequency < 0)
|
|
Mark McLoughlin |
a6e23d |
continue;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
|
|
Mark McLoughlin |
a6e23d |
@@ -350,32 +350,26 @@ static int virEventCalculateTimeout(int *timeout) {
|
|
Mark McLoughlin |
a6e23d |
* file handles. The caller must free the returned data struct
|
|
Mark McLoughlin |
a6e23d |
* returns: the pollfd array, or NULL on error
|
|
Mark McLoughlin |
a6e23d |
*/
|
|
Mark McLoughlin |
a6e23d |
-static int virEventMakePollFDs(struct pollfd **retfds) {
|
|
Mark McLoughlin |
a6e23d |
+static struct pollfd *virEventMakePollFDs(void) {
|
|
Mark McLoughlin |
a6e23d |
struct pollfd *fds;
|
|
Mark McLoughlin |
a6e23d |
- int i, nfds = 0;
|
|
Mark McLoughlin |
a6e23d |
+ int i;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
|
Mark McLoughlin |
a6e23d |
- if (eventLoop.handles[i].deleted)
|
|
Mark McLoughlin |
a6e23d |
- continue;
|
|
Mark McLoughlin |
a6e23d |
- nfds++;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
- *retfds = NULL;
|
|
Mark McLoughlin |
a6e23d |
/* Setup the poll file handle data structs */
|
|
Mark McLoughlin |
a6e23d |
- if (VIR_ALLOC_N(fds, nfds) < 0)
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
+ if (VIR_ALLOC_N(fds, eventLoop.handlesCount) < 0)
|
|
Mark McLoughlin |
a6e23d |
+ return NULL;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- for (i = 0, nfds = 0 ; i < eventLoop.handlesCount ; i++) {
|
|
Mark McLoughlin |
a6e23d |
- if (eventLoop.handles[i].deleted)
|
|
Mark McLoughlin |
a6e23d |
- continue;
|
|
Mark McLoughlin |
a6e23d |
- fds[nfds].fd = eventLoop.handles[i].fd;
|
|
Mark McLoughlin |
a6e23d |
- fds[nfds].events = eventLoop.handles[i].events;
|
|
Mark McLoughlin |
a6e23d |
- fds[nfds].revents = 0;
|
|
Mark McLoughlin |
a6e23d |
+ for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
|
Mark McLoughlin |
a6e23d |
+ EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i,
|
|
Mark McLoughlin |
a6e23d |
+ eventLoop.handles[i].watch,
|
|
Mark McLoughlin |
a6e23d |
+ eventLoop.handles[i].fd,
|
|
Mark McLoughlin |
a6e23d |
+ eventLoop.handles[i].events);
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].fd = eventLoop.handles[i].fd;
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].events = eventLoop.handles[i].events;
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].revents = 0;
|
|
Mark McLoughlin |
a6e23d |
//EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events);
|
|
Mark McLoughlin |
a6e23d |
- nfds++;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- *retfds = fds;
|
|
Mark McLoughlin |
a6e23d |
- return nfds;
|
|
Mark McLoughlin |
a6e23d |
+ return fds;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
@@ -435,26 +429,30 @@ static int virEventDispatchTimeouts(void) {
|
|
Mark McLoughlin |
a6e23d |
* Returns 0 upon success, -1 if an error occurred
|
|
Mark McLoughlin |
a6e23d |
*/
|
|
Mark McLoughlin |
a6e23d |
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
|
|
Mark McLoughlin |
a6e23d |
- int i, n;
|
|
Mark McLoughlin |
a6e23d |
+ int i;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- for (i = 0, n = 0 ; i < eventLoop.handlesCount && n < nfds ; i++) {
|
|
Mark McLoughlin |
a6e23d |
+ /* NB, use nfds not eventLoop.handlesCount, because new
|
|
Mark McLoughlin |
a6e23d |
+ * fds might be added on end of list, and they're not
|
|
Mark McLoughlin |
a6e23d |
+ * in the fds array we've got */
|
|
Mark McLoughlin |
a6e23d |
+ for (i = 0 ; i < nfds ; i++) {
|
|
Mark McLoughlin |
a6e23d |
if (eventLoop.handles[i].deleted) {
|
|
Mark McLoughlin |
a6e23d |
- EVENT_DEBUG("Skip deleted %d", eventLoop.handles[i].fd);
|
|
Mark McLoughlin |
a6e23d |
+ EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i,
|
|
Mark McLoughlin |
a6e23d |
+ eventLoop.handles[i].watch, eventLoop.handles[i].fd);
|
|
Mark McLoughlin |
a6e23d |
continue;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- if (fds[n].revents) {
|
|
Mark McLoughlin |
a6e23d |
+ if (fds[i].revents) {
|
|
Mark McLoughlin |
a6e23d |
virEventHandleCallback cb = eventLoop.handles[i].cb;
|
|
Mark McLoughlin |
a6e23d |
void *opaque = eventLoop.handles[i].opaque;
|
|
Mark McLoughlin |
a6e23d |
- int hEvents = virPollEventToEventHandleType(fds[n].revents);
|
|
Mark McLoughlin |
a6e23d |
- EVENT_DEBUG("Dispatch %d %d %p", fds[n].fd,
|
|
Mark McLoughlin |
a6e23d |
- fds[n].revents, eventLoop.handles[i].opaque);
|
|
Mark McLoughlin |
a6e23d |
+ int hEvents = virPollEventToEventHandleType(fds[i].revents);
|
|
Mark McLoughlin |
a6e23d |
+ EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].fd, eventLoop.handles[i].watch,
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].revents, eventLoop.handles[i].opaque);
|
|
Mark McLoughlin |
a6e23d |
virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
(cb)(eventLoop.handles[i].watch,
|
|
Mark McLoughlin |
a6e23d |
- fds[n].fd, hEvents, opaque);
|
|
Mark McLoughlin |
a6e23d |
+ fds[i].fd, hEvents, opaque);
|
|
Mark McLoughlin |
a6e23d |
virEventLock();
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
- n++;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
return 0;
|
|
Mark McLoughlin |
a6e23d |
@@ -545,22 +543,21 @@ static int virEventCleanupHandles(void) {
|
|
Mark McLoughlin |
a6e23d |
* at least one file handle has an event, or a timer expires
|
|
Mark McLoughlin |
a6e23d |
*/
|
|
Mark McLoughlin |
a6e23d |
int virEventRunOnce(void) {
|
|
Mark McLoughlin |
a6e23d |
- struct pollfd *fds;
|
|
Mark McLoughlin |
a6e23d |
+ struct pollfd *fds = NULL;
|
|
Mark McLoughlin |
a6e23d |
int ret, timeout, nfds;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
virEventLock();
|
|
Mark McLoughlin |
a6e23d |
eventLoop.running = 1;
|
|
Mark McLoughlin |
a6e23d |
eventLoop.leader = pthread_self();
|
|
Mark McLoughlin |
a6e23d |
- if ((nfds = virEventMakePollFDs(&fds)) < 0) {
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- if (virEventCalculateTimeout(&timeout) < 0) {
|
|
Mark McLoughlin |
a6e23d |
- VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
+ if (virEventCleanupTimeouts() < 0 ||
|
|
Mark McLoughlin |
a6e23d |
+ virEventCleanupHandles() < 0)
|
|
Mark McLoughlin |
a6e23d |
+ goto error;
|
|
Mark McLoughlin |
a6e23d |
+
|
|
Mark McLoughlin |
a6e23d |
+ if (!(fds = virEventMakePollFDs()) ||
|
|
Mark McLoughlin |
a6e23d |
+ virEventCalculateTimeout(&timeout) < 0)
|
|
Mark McLoughlin |
a6e23d |
+ goto error;
|
|
Mark McLoughlin |
a6e23d |
+ nfds = eventLoop.handlesCount;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
@@ -572,38 +569,31 @@ int virEventRunOnce(void) {
|
|
Mark McLoughlin |
a6e23d |
if (errno == EINTR) {
|
|
Mark McLoughlin |
a6e23d |
goto retry;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
- VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
+ goto error_unlocked;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
virEventLock();
|
|
Mark McLoughlin |
a6e23d |
- if (virEventDispatchTimeouts() < 0) {
|
|
Mark McLoughlin |
a6e23d |
- VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
+ if (virEventDispatchTimeouts() < 0)
|
|
Mark McLoughlin |
a6e23d |
+ goto error;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
if (ret > 0 &&
|
|
Mark McLoughlin |
a6e23d |
- virEventDispatchHandles(nfds, fds) < 0) {
|
|
Mark McLoughlin |
a6e23d |
- VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
- VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
-
|
|
Mark McLoughlin |
a6e23d |
- if (virEventCleanupTimeouts() < 0) {
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
+ virEventDispatchHandles(nfds, fds) < 0)
|
|
Mark McLoughlin |
a6e23d |
+ goto error;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
- if (virEventCleanupHandles() < 0) {
|
|
Mark McLoughlin |
a6e23d |
- virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
- return -1;
|
|
Mark McLoughlin |
a6e23d |
- }
|
|
Mark McLoughlin |
a6e23d |
+ if (virEventCleanupTimeouts() < 0 ||
|
|
Mark McLoughlin |
a6e23d |
+ virEventCleanupHandles() < 0)
|
|
Mark McLoughlin |
a6e23d |
+ goto error;
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
eventLoop.running = 0;
|
|
Mark McLoughlin |
a6e23d |
virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
+ VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
return 0;
|
|
Mark McLoughlin |
a6e23d |
+
|
|
Mark McLoughlin |
a6e23d |
+error:
|
|
Mark McLoughlin |
a6e23d |
+ virEventUnlock();
|
|
Mark McLoughlin |
a6e23d |
+error_unlocked:
|
|
Mark McLoughlin |
a6e23d |
+ VIR_FREE(fds);
|
|
Mark McLoughlin |
a6e23d |
+ return -1;
|
|
Mark McLoughlin |
a6e23d |
}
|
|
Mark McLoughlin |
a6e23d |
|
|
Mark McLoughlin |
a6e23d |
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
|
|
Mark McLoughlin |
a6e23d |
--
|
|
Mark McLoughlin |
a6e23d |
1.6.0.6
|
|
Mark McLoughlin |
a6e23d |
|