|
@@ -104,7 +104,11 @@ void qemu_aio_flush(void)
|
|
|
|
|
|
bool qemu_aio_wait(void)
|
|
|
{
|
|
|
+ AioHandler *node;
|
|
|
+ fd_set rdfds, wrfds;
|
|
|
+ int max_fd = -1;
|
|
|
int ret;
|
|
|
+ bool busy;
|
|
|
|
|
|
/*
|
|
|
* 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;
|
|
|
}
|
|
|
|
|
|
- do {
|
|
|
- AioHandler *node;
|
|
|
- fd_set rdfds, wrfds;
|
|
|
- bool busy;
|
|
|
- int max_fd = -1;
|
|
|
+ walking_handlers = 1;
|
|
|
|
|
|
- walking_handlers = 1;
|
|
|
+ FD_ZERO(&rdfds);
|
|
|
+ FD_ZERO(&wrfds);
|
|
|
|
|
|
- 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);
|
|
|
+ /* 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;
|
|
|
+ walking_handlers = 0;
|
|
|
|
|
|
- /* No AIO operations? Get us out of here */
|
|
|
- if (!busy) {
|
|
|
- return false;
|
|
|
- }
|
|
|
+ /* 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);
|
|
|
- }
|
|
|
+ /* 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;
|
|
|
+
|
|
|
+ /* 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);
|
|
|
}
|
|
|
|
|
|
- walking_handlers = 0;
|
|
|
+ tmp = node;
|
|
|
+ node = QLIST_NEXT(node, node);
|
|
|
+
|
|
|
+ if (tmp->deleted) {
|
|
|
+ QLIST_REMOVE(tmp, node);
|
|
|
+ g_free(tmp);
|
|
|
+ }
|
|
|
}
|
|
|
- } while (ret == 0);
|
|
|
+
|
|
|
+ walking_handlers = 0;
|
|
|
+ }
|
|
|
|
|
|
return true;
|
|
|
}
|