+ 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->read.fd, &pending->read.iov, 1, pending->read.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->read_cb(string_view(reinterpret_cast<char *>(pending->read.buf), pending->read.len));
+ free(pending->read.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;
+ }
+ }
+ }
+ }
+
+ // See if there are any queued stats we can submit now.
+ // Running a stat means we're very close to printing out a match,
+ // which is more important than reading more blocks from disk.
+ // (Even if those blocks returned early, they would only generate
+ // more matches that would be blocked by this one in Serializer.)
+ // Thus, prioritize stats.
+ while (!queued_stats.empty() && pending_reads < queue_depth) {