diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index ccbf5788b..0f85f70b7 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -297,23 +297,25 @@ ExportTimeoutMS(Event::Duration timeout) noexcept #ifdef HAVE_URING -static constexpr struct __kernel_timespec -ExportTimeoutKernelTimespec(Event::Duration timeout) noexcept +static struct __kernel_timespec * +ExportTimeoutKernelTimespec(Event::Duration timeout, struct __kernel_timespec &buffer) noexcept { if (timeout < timeout.zero()) - // TODO if there is no time, there should be no timeout at all - return { .tv_sec = 24 * 3600 }; + return nullptr; - if (timeout >= std::chrono::duration_cast(std::chrono::hours{24})) [[unlikely]] - return { + if (timeout >= std::chrono::duration_cast(std::chrono::hours{24})) [[unlikely]] { + buffer = { .tv_sec = std::chrono::ceil>(timeout).count(), }; + return &buffer; + } const auto nsec = std::chrono::ceil(timeout); - return { + buffer = { .tv_sec = nsec.count() / 1000000000, .tv_nsec = nsec.count() % 1000000000, }; + return &buffer; } #endif @@ -424,7 +426,8 @@ EventLoop::Run() noexcept consume all events to rearm it */ if (!epoll_ready) { - auto kernel_timeout = ExportTimeoutKernelTimespec(timeout); + struct __kernel_timespec timeout_buffer; + auto *kernel_timeout = ExportTimeoutKernelTimespec(timeout, timeout_buffer); Uring::Queue &uring_queue = *uring; uring_queue.SubmitAndWaitDispatchCompletions(kernel_timeout); } diff --git a/src/io/uring/Queue.cxx b/src/io/uring/Queue.cxx index 3e7320216..2ccfb4bdf 100644 --- a/src/io/uring/Queue.cxx +++ b/src/io/uring/Queue.cxx @@ -104,7 +104,7 @@ Queue::WaitDispatchOneCompletion() } bool -Queue::SubmitAndWaitDispatchCompletions(struct __kernel_timespec &timeout) +Queue::SubmitAndWaitDispatchCompletions(struct __kernel_timespec *timeout) { auto *cqe = ring.SubmitAndWaitCompletion(timeout); if (cqe == nullptr) diff --git a/src/io/uring/Queue.hxx b/src/io/uring/Queue.hxx index e08615f4e..57cd35f85 100644 --- a/src/io/uring/Queue.hxx +++ b/src/io/uring/Queue.hxx @@ -101,7 +101,7 @@ public: while (WaitDispatchOneCompletion()) {} } - bool SubmitAndWaitDispatchCompletions(struct __kernel_timespec &timeout); + bool SubmitAndWaitDispatchCompletions(struct __kernel_timespec *timeout); private: static void _DispatchOneCompletion(const struct io_uring_cqe &cqe) noexcept; diff --git a/src/io/uring/Ring.cxx b/src/io/uring/Ring.cxx index aac528365..c3de0dcf8 100644 --- a/src/io/uring/Ring.cxx +++ b/src/io/uring/Ring.cxx @@ -61,10 +61,10 @@ Ring::WaitCompletion() } struct io_uring_cqe * -Ring::SubmitAndWaitCompletion(struct __kernel_timespec &timeout) +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); + if (int error = io_uring_submit_and_wait_timeout(&ring, &cqe, 1, timeout, nullptr); error < 0) { if (error == -ETIME || error == -EAGAIN || error == -EINTR) return nullptr; diff --git a/src/io/uring/Ring.hxx b/src/io/uring/Ring.hxx index f5033f6aa..06a32f617 100644 --- a/src/io/uring/Ring.hxx +++ b/src/io/uring/Ring.hxx @@ -109,7 +109,7 @@ public: * * @return a completion queue entry or nullptr on EAGAIN/ETIME */ - struct io_uring_cqe *SubmitAndWaitCompletion(struct __kernel_timespec &timeout); + struct io_uring_cqe *SubmitAndWaitCompletion(struct __kernel_timespec *timeout); /** * Peek one completion (non-blocking).