- PendingRead *pending = reinterpret_cast<PendingRead *>(cqe->user_data);
- if (cqe->res <= 0) {
- fprintf(stderr, "async read failed: %s\n", strerror(-cqe->res));
- exit(1);
- }
+ unsigned head;
+ io_uring_for_each_cqe(&ring, head, cqe)
+ {
+ PendingRead *pending = reinterpret_cast<PendingRead *>(cqe->user_data);
+ if (pending->op == OP_STAT) {
+ io_uring_cqe_seen(&ring, cqe);
+ --pending_reads;
+
+ size_t old_pending_reads = pending_reads;
+ pending->stat_cb();
+ free(pending->stat.pathname);
+ delete pending->stat.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;
+ }
+ } else {
+ if (cqe->res <= 0) {
+ fprintf(stderr, "async read failed: %s\n", strerror(-cqe->res));
+ exit(1);
+ }
+
+ if (size_t(cqe->res) < pending->read.iov.iov_len) {
+ // Incomplete read, so resubmit it.
+ pending->read.iov.iov_base = (char *)pending->read.iov.iov_base + cqe->res;
+ pending->read.iov.iov_len -= cqe->res;
+ pending->read.offset += cqe->res;
+ io_uring_cqe_seen(&ring, cqe);