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:
parent
bcdc18578d
commit
9eb0bfca96
133
aio.c
133
aio.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue