mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-26 18:41:17 +00:00
Fix watch/timer event deletion
This commit is contained in:
parent
0a31be6ba2
commit
470317f5c7
@ -1,3 +1,10 @@
|
|||||||
|
Tue May 12 17:43:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Fix watch/timer event deletion
|
||||||
|
* qemud/event.c: Change handling of deleted watches/timers
|
||||||
|
to ensure correct dispatch of callbacks when deleted flag
|
||||||
|
is set
|
||||||
|
|
||||||
Tue May 12 17:42:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
Tue May 12 17:42:22 BST 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
* qemud/event.c: Start watch/timer IDs from 1 to avoid problem
|
* qemud/event.c: Start watch/timer IDs from 1 to avoid problem
|
||||||
|
114
qemud/event.c
114
qemud/event.c
@ -313,7 +313,7 @@ static int virEventCalculateTimeout(int *timeout) {
|
|||||||
EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount);
|
EVENT_DEBUG("Calculate expiry of %d timers", eventLoop.timeoutsCount);
|
||||||
/* Figure out if we need a timeout */
|
/* Figure out if we need a timeout */
|
||||||
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
for (i = 0 ; i < eventLoop.timeoutsCount ; i++) {
|
||||||
if (eventLoop.timeouts[i].deleted || eventLoop.timeouts[i].frequency < 0)
|
if (eventLoop.timeouts[i].frequency < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
|
EVENT_DEBUG("Got a timeout scheduled for %llu", eventLoop.timeouts[i].expiresAt);
|
||||||
@ -350,32 +350,26 @@ static int virEventCalculateTimeout(int *timeout) {
|
|||||||
* file handles. The caller must free the returned data struct
|
* file handles. The caller must free the returned data struct
|
||||||
* returns: the pollfd array, or NULL on error
|
* returns: the pollfd array, or NULL on error
|
||||||
*/
|
*/
|
||||||
static int virEventMakePollFDs(struct pollfd **retfds) {
|
static struct pollfd *virEventMakePollFDs(void) {
|
||||||
struct pollfd *fds;
|
struct pollfd *fds;
|
||||||
int i, nfds = 0;
|
int i;
|
||||||
|
|
||||||
|
/* Setup the poll file handle data structs */
|
||||||
|
if (VIR_ALLOC_N(fds, eventLoop.handlesCount) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
for (i = 0 ; i < eventLoop.handlesCount ; i++) {
|
||||||
if (eventLoop.handles[i].deleted)
|
EVENT_DEBUG("Prepare n=%d w=%d, f=%d e=%d", i,
|
||||||
continue;
|
eventLoop.handles[i].watch,
|
||||||
nfds++;
|
eventLoop.handles[i].fd,
|
||||||
}
|
eventLoop.handles[i].events);
|
||||||
*retfds = NULL;
|
fds[i].fd = eventLoop.handles[i].fd;
|
||||||
/* Setup the poll file handle data structs */
|
fds[i].events = eventLoop.handles[i].events;
|
||||||
if (VIR_ALLOC_N(fds, nfds) < 0)
|
fds[i].revents = 0;
|
||||||
return -1;
|
|
||||||
|
|
||||||
for (i = 0, nfds = 0 ; i < eventLoop.handlesCount ; i++) {
|
|
||||||
if (eventLoop.handles[i].deleted)
|
|
||||||
continue;
|
|
||||||
fds[nfds].fd = eventLoop.handles[i].fd;
|
|
||||||
fds[nfds].events = eventLoop.handles[i].events;
|
|
||||||
fds[nfds].revents = 0;
|
|
||||||
//EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events);
|
//EVENT_DEBUG("Wait for %d %d", eventLoop.handles[i].fd, eventLoop.handles[i].events);
|
||||||
nfds++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*retfds = fds;
|
return fds;
|
||||||
return nfds;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -435,26 +429,30 @@ static int virEventDispatchTimeouts(void) {
|
|||||||
* Returns 0 upon success, -1 if an error occurred
|
* Returns 0 upon success, -1 if an error occurred
|
||||||
*/
|
*/
|
||||||
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
|
static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
|
||||||
int i, n;
|
int i;
|
||||||
|
|
||||||
for (i = 0, n = 0 ; i < eventLoop.handlesCount && n < nfds ; i++) {
|
/* NB, use nfds not eventLoop.handlesCount, because new
|
||||||
|
* fds might be added on end of list, and they're not
|
||||||
|
* in the fds array we've got */
|
||||||
|
for (i = 0 ; i < nfds ; i++) {
|
||||||
if (eventLoop.handles[i].deleted) {
|
if (eventLoop.handles[i].deleted) {
|
||||||
EVENT_DEBUG("Skip deleted %d", eventLoop.handles[i].fd);
|
EVENT_DEBUG("Skip deleted n=%d w=%d f=%d", i,
|
||||||
|
eventLoop.handles[i].watch, eventLoop.handles[i].fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fds[n].revents) {
|
if (fds[i].revents) {
|
||||||
virEventHandleCallback cb = eventLoop.handles[i].cb;
|
virEventHandleCallback cb = eventLoop.handles[i].cb;
|
||||||
void *opaque = eventLoop.handles[i].opaque;
|
void *opaque = eventLoop.handles[i].opaque;
|
||||||
int hEvents = virPollEventToEventHandleType(fds[n].revents);
|
int hEvents = virPollEventToEventHandleType(fds[i].revents);
|
||||||
EVENT_DEBUG("Dispatch %d %d %p", fds[n].fd,
|
EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
|
||||||
fds[n].revents, eventLoop.handles[i].opaque);
|
fds[i].fd, eventLoop.handles[i].watch,
|
||||||
|
fds[i].revents, eventLoop.handles[i].opaque);
|
||||||
virEventUnlock();
|
virEventUnlock();
|
||||||
(cb)(eventLoop.handles[i].watch,
|
(cb)(eventLoop.handles[i].watch,
|
||||||
fds[n].fd, hEvents, opaque);
|
fds[i].fd, hEvents, opaque);
|
||||||
virEventLock();
|
virEventLock();
|
||||||
}
|
}
|
||||||
n++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -545,22 +543,21 @@ static int virEventCleanupHandles(void) {
|
|||||||
* at least one file handle has an event, or a timer expires
|
* at least one file handle has an event, or a timer expires
|
||||||
*/
|
*/
|
||||||
int virEventRunOnce(void) {
|
int virEventRunOnce(void) {
|
||||||
struct pollfd *fds;
|
struct pollfd *fds = NULL;
|
||||||
int ret, timeout, nfds;
|
int ret, timeout, nfds;
|
||||||
|
|
||||||
virEventLock();
|
virEventLock();
|
||||||
eventLoop.running = 1;
|
eventLoop.running = 1;
|
||||||
eventLoop.leader = pthread_self();
|
eventLoop.leader = pthread_self();
|
||||||
if ((nfds = virEventMakePollFDs(&fds)) < 0) {
|
|
||||||
virEventUnlock();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (virEventCalculateTimeout(&timeout) < 0) {
|
if (virEventCleanupTimeouts() < 0 ||
|
||||||
VIR_FREE(fds);
|
virEventCleanupHandles() < 0)
|
||||||
virEventUnlock();
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
if (!(fds = virEventMakePollFDs()) ||
|
||||||
|
virEventCalculateTimeout(&timeout) < 0)
|
||||||
|
goto error;
|
||||||
|
nfds = eventLoop.handlesCount;
|
||||||
|
|
||||||
virEventUnlock();
|
virEventUnlock();
|
||||||
|
|
||||||
@ -572,38 +569,31 @@ int virEventRunOnce(void) {
|
|||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
VIR_FREE(fds);
|
goto error_unlocked;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virEventLock();
|
virEventLock();
|
||||||
if (virEventDispatchTimeouts() < 0) {
|
if (virEventDispatchTimeouts() < 0)
|
||||||
VIR_FREE(fds);
|
goto error;
|
||||||
virEventUnlock();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret > 0 &&
|
if (ret > 0 &&
|
||||||
virEventDispatchHandles(nfds, fds) < 0) {
|
virEventDispatchHandles(nfds, fds) < 0)
|
||||||
VIR_FREE(fds);
|
goto error;
|
||||||
virEventUnlock();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
VIR_FREE(fds);
|
|
||||||
|
|
||||||
if (virEventCleanupTimeouts() < 0) {
|
if (virEventCleanupTimeouts() < 0 ||
|
||||||
virEventUnlock();
|
virEventCleanupHandles() < 0)
|
||||||
return -1;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
if (virEventCleanupHandles() < 0) {
|
|
||||||
virEventUnlock();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventLoop.running = 0;
|
eventLoop.running = 0;
|
||||||
virEventUnlock();
|
virEventUnlock();
|
||||||
|
VIR_FREE(fds);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virEventUnlock();
|
||||||
|
error_unlocked:
|
||||||
|
VIR_FREE(fds);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
|
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
|
||||||
|
Loading…
Reference in New Issue
Block a user