]> git.sesse.net Git - plocate/blobdiff - io_uring_engine.cpp
Move exception shifting to later; allows us to get it into SSE2.
[plocate] / io_uring_engine.cpp
index fb0a4de443d25ec99ff13ff6c1b11ca6a5897962..f8295aacfde48f99e929a4dc2e0656b4f80dcd19 100644 (file)
@@ -69,54 +69,64 @@ void IOUringEngine::finish()
        }
 
 #ifndef WITHOUT_URING
-       int ret = io_uring_submit(&ring);
-       if (ret < 0) {
-               fprintf(stderr, "io_uring_submit: %s\n", strerror(-ret));
-               exit(1);
-       }
-       bool anything_to_submit = false;
+       bool anything_to_submit = true;
        while (pending_reads > 0) {
                io_uring_cqe *cqe;
-               ret = io_uring_wait_cqe(&ring, &cqe);
-               if (ret < 0) {
-                       fprintf(stderr, "io_uring_wait_cqe: %s\n", strerror(-ret));
-                       exit(1);
-               }
-
-               PendingRead *pending = reinterpret_cast<PendingRead *>(cqe->user_data);
-               if (cqe->res <= 0) {
-                       fprintf(stderr, "async read failed: %s\n", strerror(-cqe->res));
-                       exit(1);
+               if (io_uring_peek_cqe(&ring, &cqe) != 0) {
+                       if (anything_to_submit) {
+                               // Nothing ready, so submit whatever is pending and then do a blocking wait.
+                               int ret = io_uring_submit_and_wait(&ring, 1);
+                               if (ret < 0) {
+                                       fprintf(stderr, "io_uring_submit(queued): %s\n", strerror(-ret));
+                                       exit(1);
+                               }
+                               anything_to_submit = false;
+                       } else {
+                               int ret = io_uring_wait_cqe(&ring, &cqe);
+                               if (ret < 0) {
+                                       fprintf(stderr, "io_uring_wait_cqe: %s\n", strerror(-ret));
+                                       exit(1);
+                               }
+                       }
                }
 
-               if (size_t(cqe->res) < pending->iov.iov_len) {
-                       // Incomplete read, so resubmit it.
-                       pending->iov.iov_base = (char *)pending->iov.iov_base + cqe->res;
-                       pending->iov.iov_len -= cqe->res;
-                       pending->offset += cqe->res;
-                       io_uring_cqe_seen(&ring, cqe);
-
-                       io_uring_sqe *sqe = io_uring_get_sqe(&ring);
-                       if (sqe == nullptr) {
-                               fprintf(stderr, "No free SQE for resubmit; this shouldn't happen.\n");
+               unsigned head;
+               io_uring_for_each_cqe(&ring, head, cqe) {
+                       PendingRead *pending = reinterpret_cast<PendingRead *>(cqe->user_data);
+                       if (cqe->res <= 0) {
+                               fprintf(stderr, "async read failed: %s\n", strerror(-cqe->res));
                                exit(1);
                        }
-                       io_uring_prep_readv(sqe, pending->fd, &pending->iov, 1, pending->offset);
-                       io_uring_sqe_set_data(sqe, pending);
-                       anything_to_submit = true;
-               } else {
-                       io_uring_cqe_seen(&ring, cqe);
-                       --pending_reads;
-
-                       size_t old_pending_reads = pending_reads;
-                       pending->cb(string(reinterpret_cast<char *>(pending->buf), pending->len));
-                       free(pending->buf);
-                       delete pending;
-
-                       if (pending_reads != old_pending_reads) {
-                               // A new read was made in the callback (and not queued),
-                               // so we need to re-submit.
+
+                       if (size_t(cqe->res) < pending->iov.iov_len) {
+                               // Incomplete read, so resubmit it.
+                               pending->iov.iov_base = (char *)pending->iov.iov_base + cqe->res;
+                               pending->iov.iov_len -= cqe->res;
+                               pending->offset += cqe->res;
+                               io_uring_cqe_seen(&ring, cqe);
+
+                               io_uring_sqe *sqe = io_uring_get_sqe(&ring);
+                               if (sqe == nullptr) {
+                                       fprintf(stderr, "No free SQE for resubmit; this shouldn't happen.\n");
+                                       exit(1);
+                               }
+                               io_uring_prep_readv(sqe, pending->fd, &pending->iov, 1, pending->offset);
+                               io_uring_sqe_set_data(sqe, pending);
                                anything_to_submit = true;
+                       } else {
+                               io_uring_cqe_seen(&ring, cqe);
+                               --pending_reads;
+
+                               size_t old_pending_reads = pending_reads;
+                               pending->cb(string(reinterpret_cast<char *>(pending->buf), pending->len));
+                               free(pending->buf);
+                               delete pending;
+
+                               if (pending_reads != old_pending_reads) {
+                                       // A new read was made in the callback (and not queued),
+                                       // so we need to re-submit.
+                                       anything_to_submit = true;
+                               }
                        }
                }
 
@@ -132,17 +142,6 @@ void IOUringEngine::finish()
                        queued_reads.pop();
                        anything_to_submit = true;
                }
-
-               if (anything_to_submit) {
-                       // A new read was made, so we need to re-submit.
-                       int ret = io_uring_submit(&ring);
-                       if (ret < 0) {
-                               fprintf(stderr, "io_uring_submit(queued): %s\n", strerror(-ret));
-                               exit(1);
-                       } else {
-                               anything_to_submit = false;
-                       }
-               }
        }
 #endif
 }