diff -rup libvirt-0.6.0.orig/qemud/event.c libvirt-0.6.0.new/qemud/event.c --- libvirt-0.6.0.orig/qemud/event.c 2008-12-22 13:02:54.000000000 +0000 +++ libvirt-0.6.0.new/qemud/event.c 2009-02-06 19:29:28.000000000 +0000 @@ -68,6 +68,7 @@ struct virEventTimeout { /* State for the main event loop */ struct virEventLoop { pthread_mutex_t lock; + int running; pthread_t leader; int wakeupfd[2]; int handlesCount; @@ -521,6 +522,7 @@ int virEventRunOnce(void) { int ret, timeout, nfds; virEventLock(); + eventLoop.running = 1; eventLoop.leader = pthread_self(); if ((nfds = virEventMakePollFDs(&fds)) < 0) { virEventUnlock(); @@ -572,7 +574,7 @@ int virEventRunOnce(void) { return -1; } - eventLoop.leader = 0; + eventLoop.running = 0; virEventUnlock(); return 0; } @@ -611,7 +613,9 @@ int virEventInit(void) static int virEventInterruptLocked(void) { char c = '\0'; - if (pthread_self() == eventLoop.leader) + + if (!eventLoop.running || + pthread_self() == eventLoop.leader) return 0; if (safewrite(eventLoop.wakeupfd[1], &c, sizeof(c)) != sizeof(c)) diff -rup libvirt-0.6.0.orig/qemud/qemud.c libvirt-0.6.0.new/qemud/qemud.c --- libvirt-0.6.0.orig/qemud/qemud.c 2009-01-31 09:04:17.000000000 +0000 +++ libvirt-0.6.0.new/qemud/qemud.c 2009-02-06 19:29:28.000000000 +0000 @@ -2013,11 +2013,15 @@ static int qemudOneLoop(void) { return 0; } -static void qemudInactiveTimer(int timer ATTRIBUTE_UNUSED, void *data) { +static void qemudInactiveTimer(int timerid, void *data) { struct qemud_server *server = (struct qemud_server *)data; - DEBUG0("Got inactive timer expiry"); - if (!virStateActive()) { - DEBUG0("No state active, shutting down"); + + if (virStateActive() || + server->clients) { + DEBUG0("Timer expired but still active, not shutting down"); + virEventUpdateTimeoutImpl(timerid, -1); + } else { + DEBUG0("Timer expired and inactive, shutting down"); server->shutdown = 1; } } @@ -2048,9 +2052,18 @@ static void qemudFreeClient(struct qemud static int qemudRunLoop(struct qemud_server *server) { int timerid = -1; int ret = -1, i; + int timerActive = 0; virMutexLock(&server->lock); + if (timeout > 0 && + (timerid = virEventAddTimeoutImpl(-1, + qemudInactiveTimer, + server, NULL)) < 0) { + VIR_ERROR0(_("Failed to register shutdown timeout")); + return -1; + } + if (min_workers > max_workers) max_workers = min_workers; @@ -2071,11 +2084,21 @@ static int qemudRunLoop(struct qemud_ser * if any drivers have active state, if not * shutdown after timeout seconds */ - if (timeout > 0 && !virStateActive() && !server->clients) { - timerid = virEventAddTimeoutImpl(timeout*1000, - qemudInactiveTimer, - server, NULL); - DEBUG("Scheduling shutdown timer %d", timerid); + if (timeout > 0) { + if (timerActive) { + if (server->clients) { + DEBUG("Deactivating shutdown timer %d", timerid); + virEventUpdateTimeoutImpl(timerid, -1); + timerActive = 0; + } + } else { + if (!virStateActive() && + !server->clients) { + DEBUG("Activating shutdown timer %d", timerid); + virEventUpdateTimeoutImpl(timerid, timeout * 1000); + timerActive = 1; + } + } } virMutexUnlock(&server->lock); @@ -2129,15 +2152,6 @@ static int qemudRunLoop(struct qemud_ser } } - /* Unregister any timeout that's active, since we - * just had an event processed - */ - if (timerid != -1) { - DEBUG("Removing shutdown timer %d", timerid); - virEventRemoveTimeoutImpl(timerid); - timerid = -1; - } - if (server->shutdown) { ret = 0; break;