From e014d319724d398048d0de38e558c2aca74c7a70 Mon Sep 17 00:00:00 2001 From: Max Kellermann <max.kellermann@ionos.com> 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 066797354..9b4cd050d 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 6f88ee516..02d4fbdff 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 222b24363..cd7c7721d 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 8c1128995..987c9fffd 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). *