]> git.proxmox.com Git - qemu.git/blobdiff - aio.c
Update version for 1.1.0-rc4 release
[qemu.git] / aio.c
diff --git a/aio.c b/aio.c
index 1239ca7bd2ad37bed6b51d33d7f35f60571d8552..0a9eb10c76dc07c033560eab13b3eb5dded059b2 100644 (file)
--- a/aio.c
+++ b/aio.c
@@ -9,6 +9,8 @@
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  *
+ * Contributions after 2012-01-13 are licensed under the terms of the
+ * GNU GPL, version 2 or (at your option) any later version.
  */
 
 #include "qemu-common.h"
@@ -33,7 +35,6 @@ struct AioHandler
     IOHandler *io_read;
     IOHandler *io_write;
     AioFlushHandler *io_flush;
-    AioProcessQueue *io_process_queue;
     int deleted;
     void *opaque;
     QLIST_ENTRY(AioHandler) node;
@@ -56,7 +57,6 @@ int qemu_aio_set_fd_handler(int fd,
                             IOHandler *io_read,
                             IOHandler *io_write,
                             AioFlushHandler *io_flush,
-                            AioProcessQueue *io_process_queue,
                             void *opaque)
 {
     AioHandler *node;
@@ -89,7 +89,6 @@ int qemu_aio_set_fd_handler(int fd,
         node->io_read = io_read;
         node->io_write = io_write;
         node->io_flush = io_flush;
-        node->io_process_queue = io_process_queue;
         node->opaque = opaque;
     }
 
@@ -100,131 +99,96 @@ int qemu_aio_set_fd_handler(int fd,
 
 void qemu_aio_flush(void)
 {
-    AioHandler *node;
-    int ret;
-
-    do {
-        ret = 0;
-
-       /*
-        * If there are pending emulated aio start them now so flush
-        * will be able to return 1.
-        */
-        qemu_aio_wait();
-
-        QLIST_FOREACH(node, &aio_handlers, node) {
-            if (node->io_flush) {
-                ret |= node->io_flush(node->opaque);
-            }
-        }
-    } while (qemu_bh_poll() || ret > 0);
+    while (qemu_aio_wait());
 }
 
-int qemu_aio_process_queue(void)
+bool qemu_aio_wait(void)
 {
     AioHandler *node;
-    int ret = 0;
+    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.
+     * Do not call select in this case, because it is possible that the caller
+     * does not need a complete flush (as is the case for qemu_aio_wait loops).
+     */
+    if (qemu_bh_poll()) {
+        return true;
+    }
 
     walking_handlers = 1;
 
+    FD_ZERO(&rdfds);
+    FD_ZERO(&wrfds);
+
+    /* fill fd sets */
+    busy = false;
     QLIST_FOREACH(node, &aio_handlers, node) {
-        if (node->io_process_queue) {
-            if (node->io_process_queue(node->opaque)) {
-                ret = 1;
+        /* 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;
 
-    return ret;
-}
-
-void qemu_aio_wait(void)
-{
-    int ret;
-
-    if (qemu_bh_poll())
-        return;
-
-    /*
-     * If there are callbacks left that have been queued, we need to call then.
-     * Return afterwards to avoid waiting needlessly in select().
-     */
-    if (qemu_aio_process_queue())
-        return;
+    /* No AIO operations?  Get us out of here */
+    if (!busy) {
+        return false;
+    }
 
-    do {
-        AioHandler *node;
-        fd_set rdfds, wrfds;
-        int max_fd = -1;
+    /* 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;
 
-        FD_ZERO(&rdfds);
-        FD_ZERO(&wrfds);
+        /* 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;
 
-        /* fill fd sets */
-        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 && node->io_flush(node->opaque) == 0)
-                continue;
-
-            if (!node->deleted && node->io_read) {
-                FD_SET(node->fd, &rdfds);
-                max_fd = MAX(max_fd, node->fd + 1);
+            if (!node->deleted &&
+                FD_ISSET(node->fd, &rdfds) &&
+                node->io_read) {
+                node->io_read(node->opaque);
             }
-            if (!node->deleted && node->io_write) {
-                FD_SET(node->fd, &wrfds);
-                max_fd = MAX(max_fd, node->fd + 1);
+            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);
 
-        /* No AIO operations?  Get us out of here */
-        if (max_fd == -1)
-            break;
-
-        /* 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);
-                }
+            if (tmp->deleted) {
+                QLIST_REMOVE(tmp, node);
+                g_free(tmp);
             }
-
-            walking_handlers = 0;
         }
-    } while (ret == 0);
+
+        walking_handlers = 0;
+    }
+
+    return true;
 }