diff --git a/src/io/uring/CancellableOperation.hxx b/src/io/uring/CancellableOperation.hxx index 02fb8f097..9c6b81813 100644 --- a/src/io/uring/CancellableOperation.hxx +++ b/src/io/uring/CancellableOperation.hxx @@ -48,14 +48,19 @@ public: new_operation.cancellable = this; } - void OnUringCompletion(int res) noexcept { + void OnUringCompletion(int res, bool more) noexcept { if (operation == nullptr) return; assert(operation->cancellable == this); - operation->cancellable = nullptr; - std::exchange(operation, nullptr)->OnUringCompletion(res); + if (more) { + operation->OnUringCompletion(res); + } else { + operation->cancellable = nullptr; + + std::exchange(operation, nullptr)->OnUringCompletion(res); + } } }; diff --git a/src/io/uring/Queue.cxx b/src/io/uring/Queue.cxx index 2ce9f220e..066797354 100644 --- a/src/io/uring/Queue.cxx +++ b/src/io/uring/Queue.cxx @@ -57,9 +57,12 @@ Queue::DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept void *data = io_uring_cqe_get_data(&cqe); if (data != nullptr) { auto *c = (CancellableOperation *)data; - c->OnUringCompletion(cqe.res); - c->unlink(); - delete c; + const bool more = cqe.flags & IORING_CQE_F_MORE; + c->OnUringCompletion(cqe.res, more); + if (!more) { + c->unlink(); + delete c; + } } ring.SeenCompletion(cqe);