render / rpms / libvirt

Forked from rpms/libvirt 10 months ago
Clone
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