- 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);