aio: simplify qemu_aio_wait

The do...while loop can never loop, because select will just not return
0 when invoked with infinite timeout.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Paolo Bonzini 2012-04-12 14:00:56 +02:00 committed by Kevin Wolf
parent bcdc18578d
commit 9eb0bfca96

133
aio.c
View file

@ -104,7 +104,11 @@ void qemu_aio_flush(void)
bool qemu_aio_wait(void) bool qemu_aio_wait(void)
{ {
AioHandler *node;
fd_set rdfds, wrfds;
int max_fd = -1;
int ret; int ret;
bool busy;
/* /*
* If there are callbacks left that have been queued, we need to call then. * If there are callbacks left that have been queued, we need to call then.
@ -115,85 +119,76 @@ bool qemu_aio_wait(void)
return true; return true;
} }
do { walking_handlers = 1;
AioHandler *node;
fd_set rdfds, wrfds;
bool busy;
int max_fd = -1;
FD_ZERO(&rdfds);
FD_ZERO(&wrfds);
/* fill fd sets */
busy = false;
QLIST_FOREACH(node, &aio_handlers, node) {
/* If there aren't pending AIO operations, don't invoke callbacks.
* Otherwise, if there are no AIO requests, qemu_aio_wait() would
* wait indefinitely.
*/
if (node->io_flush) {
if (node->io_flush(node->opaque) == 0) {
continue;
}
busy = true;
}
if (!node->deleted && node->io_read) {
FD_SET(node->fd, &rdfds);
max_fd = MAX(max_fd, node->fd + 1);
}
if (!node->deleted && node->io_write) {
FD_SET(node->fd, &wrfds);
max_fd = MAX(max_fd, node->fd + 1);
}
}
walking_handlers = 0;
/* No AIO operations? Get us out of here */
if (!busy) {
return false;
}
/* wait until next event */
ret = select(max_fd, &rdfds, &wrfds, NULL, NULL);
/* if we have any readable fds, dispatch event */
if (ret > 0) {
walking_handlers = 1; walking_handlers = 1;
FD_ZERO(&rdfds); /* we have to walk very carefully in case
FD_ZERO(&wrfds); * qemu_aio_set_fd_handler is called while we're walking */
node = QLIST_FIRST(&aio_handlers);
while (node) {
AioHandler *tmp;
/* fill fd sets */ if (!node->deleted &&
busy = false; FD_ISSET(node->fd, &rdfds) &&
QLIST_FOREACH(node, &aio_handlers, node) { node->io_read) {
/* If there aren't pending AIO operations, don't invoke callbacks. node->io_read(node->opaque);
* Otherwise, if there are no AIO requests, qemu_aio_wait() would
* wait indefinitely.
*/
if (node->io_flush) {
if (node->io_flush(node->opaque) == 0) {
continue;
}
busy = true;
} }
if (!node->deleted && node->io_read) { if (!node->deleted &&
FD_SET(node->fd, &rdfds); FD_ISSET(node->fd, &wrfds) &&
max_fd = MAX(max_fd, node->fd + 1); node->io_write) {
node->io_write(node->opaque);
} }
if (!node->deleted && node->io_write) {
FD_SET(node->fd, &wrfds); tmp = node;
max_fd = MAX(max_fd, node->fd + 1); node = QLIST_NEXT(node, node);
if (tmp->deleted) {
QLIST_REMOVE(tmp, node);
g_free(tmp);
} }
} }
walking_handlers = 0; walking_handlers = 0;
}
/* No AIO operations? Get us out of here */
if (!busy) {
return false;
}
/* wait until next event */
ret = select(max_fd, &rdfds, &wrfds, NULL, NULL);
if (ret == -1 && errno == EINTR)
continue;
/* if we have any readable fds, dispatch event */
if (ret > 0) {
walking_handlers = 1;
/* we have to walk very carefully in case
* qemu_aio_set_fd_handler is called while we're walking */
node = QLIST_FIRST(&aio_handlers);
while (node) {
AioHandler *tmp;
if (!node->deleted &&
FD_ISSET(node->fd, &rdfds) &&
node->io_read) {
node->io_read(node->opaque);
}
if (!node->deleted &&
FD_ISSET(node->fd, &wrfds) &&
node->io_write) {
node->io_write(node->opaque);
}
tmp = node;
node = QLIST_NEXT(node, node);
if (tmp->deleted) {
QLIST_REMOVE(tmp, node);
g_free(tmp);
}
}
walking_handlers = 0;
}
} while (ret == 0);
return true; return true;
} }