From 02c692adb45f6f075e956dd7f077365e88fcefb6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 1 Feb 2025 20:50:14 +0100 Subject: [PATCH] io/uring/Ring: add io_uring_submit_and_wait_timeout() wrapper --- src/io/uring/Queue.cxx | 11 +++++++++++ src/io/uring/Queue.hxx | 2 ++ src/io/uring/Ring.cxx | 15 +++++++++++++++ src/io/uring/Ring.hxx | 10 ++++++++++ 4 files changed, 38 insertions(+) diff --git a/src/io/uring/Queue.cxx b/src/io/uring/Queue.cxx index 06679735..9b4cd050 100644 --- a/src/io/uring/Queue.cxx +++ b/src/io/uring/Queue.cxx @@ -90,4 +90,15 @@ Queue::WaitDispatchOneCompletion() return true; } +bool +Queue::SubmitAndWaitDispatchOneCompletion(struct __kernel_timespec &timeout) +{ + auto *cqe = ring.SubmitAndWaitCompletion(timeout); + if (cqe == nullptr) + return false; + + DispatchOneCompletion(*cqe); + return true; +} + } // namespace Uring diff --git a/src/io/uring/Queue.hxx b/src/io/uring/Queue.hxx index 6f88ee51..02d4fbdf 100644 --- a/src/io/uring/Queue.hxx +++ b/src/io/uring/Queue.hxx @@ -101,6 +101,8 @@ public: while (WaitDispatchOneCompletion()) {} } + bool SubmitAndWaitDispatchOneCompletion(struct __kernel_timespec &timeout); + private: void DispatchOneCompletion(struct io_uring_cqe &cqe) noexcept; }; diff --git a/src/io/uring/Ring.cxx b/src/io/uring/Ring.cxx index 222b2436..cd7c7721 100644 --- a/src/io/uring/Ring.cxx +++ b/src/io/uring/Ring.cxx @@ -60,6 +60,21 @@ Ring::WaitCompletion() return cqe; } +struct io_uring_cqe * +Ring::SubmitAndWaitCompletion(struct __kernel_timespec &timeout) +{ + struct io_uring_cqe *cqe; + if (int error = io_uring_submit_and_wait_timeout(&ring, &cqe, 1, &timeout, nullptr); + error < 0) { + if (error == -ETIME || error == -EAGAIN) + return nullptr; + + throw MakeErrno(-error, "io_uring_submit_and_wait_timeout() failed"); + } + + return cqe; +} + struct io_uring_cqe * Ring::PeekCompletion() { diff --git a/src/io/uring/Ring.hxx b/src/io/uring/Ring.hxx index 8c112899..987c9fff 100644 --- a/src/io/uring/Ring.hxx +++ b/src/io/uring/Ring.hxx @@ -101,6 +101,16 @@ public: */ struct io_uring_cqe *WaitCompletion(); + /** + * Submit requests and wait for one completion (or a timeout). + * Wrapper for io_uring_submit_and_wait_timeout(). + * + * Throws on error. + * + * @return a completion queue entry or nullptr on EAGAIN/ETIME + */ + struct io_uring_cqe *SubmitAndWaitCompletion(struct __kernel_timespec &timeout); + /** * Peek one completion (non-blocking). *