diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index f2b42af6b..694ec3c65 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -13,8 +13,6 @@ #ifdef HAVE_URING #include "uring/Manager.hxx" -#include "util/PrintException.hxx" -#include <stdio.h> #endif EventLoop::EventLoop( @@ -53,26 +51,46 @@ EventLoop::~EventLoop() noexcept assert(ready_sockets.empty()); } +void +EventLoop::SetVolatile() noexcept +{ #ifdef HAVE_URING + if (uring) + uring->SetVolatile(); +#endif +} + +#ifdef HAVE_URING + +void +EventLoop::EnableUring(unsigned entries, unsigned flags) +{ + assert(!uring); + + uring = std::make_unique<Uring::Manager>(*this, entries, flags); +} + +void +EventLoop::EnableUring(unsigned entries, struct io_uring_params ¶ms) +{ + assert(!uring); + + uring = std::make_unique<Uring::Manager>(*this, entries, params); +} + +void +EventLoop::DisableUring() noexcept +{ + uring.reset(); +} Uring::Queue * EventLoop::GetUring() noexcept { - if (!uring_initialized) { - uring_initialized = true; - try { - uring = std::make_unique<Uring::Manager>(*this, 1024, - IORING_SETUP_SINGLE_ISSUER); - } catch (...) { - fprintf(stderr, "Failed to initialize io_uring: "); - PrintException(std::current_exception()); - } - } - return uring.get(); } -#endif +#endif // HAVE_URING bool EventLoop::AddFD(int fd, unsigned events, SocketEvent &event) noexcept @@ -280,17 +298,6 @@ EventLoop::Run() noexcept wake_event.Schedule(SocketEvent::READ); #endif -#ifdef HAVE_URING - AtScopeExit(this) { - /* make sure that the Uring::Manager gets destructed - from within the EventThread, or else its - destruction in another thread will cause assertion - failures */ - uring.reset(); - uring_initialized = false; - }; -#endif - #ifdef HAVE_THREADED_EVENT_LOOP AtScopeExit(this) { wake_event.Cancel(); diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 5163bcb70..eaee88c9a 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -27,6 +27,7 @@ #include "io/uring/Features.h" #ifdef HAVE_URING #include <memory> +struct io_uring_params; namespace Uring { class Queue; class Manager; } #endif @@ -133,10 +134,6 @@ class EventLoop final bool busy = true; #endif -#ifdef HAVE_URING - bool uring_initialized = false; -#endif - ClockCache<std::chrono::steady_clock> steady_clock_cache; public: @@ -185,8 +182,27 @@ public: steady_clock_cache.flush(); } + void SetVolatile() noexcept; + #ifdef HAVE_URING - [[gnu::pure]] + /** + * Try to enable io_uring support. If this method succeeds, + * GetUring() can be used to obtain a pointer to the queue + * instance. + * + * Throws on error. + */ + void EnableUring(unsigned entries, unsigned flags); + void EnableUring(unsigned entries, struct io_uring_params ¶ms); + + void DisableUring() noexcept; + + /** + * Returns a pointer to the io_uring queue instance or nullptr + * if io_uring support is not available (or was not enabled + * using EnableUring()). + */ + [[nodiscard]] [[gnu::const]] Uring::Queue *GetUring() noexcept; #endif diff --git a/src/event/Thread.cxx b/src/event/Thread.cxx index d756171c9..70e1feb4f 100644 --- a/src/event/Thread.cxx +++ b/src/event/Thread.cxx @@ -9,6 +9,11 @@ #include "util/Domain.hxx" #include "Log.hxx" +#ifdef HAVE_URING +#include "util/ScopeExit.hxx" +#include <liburing.h> +#endif + static constexpr Domain event_domain("event"); void @@ -51,7 +56,27 @@ EventThread::Run() noexcept "RTIOThread could not get realtime scheduling, continuing anyway: {}", std::current_exception()); } + } else { +#ifdef HAVE_URING + try { + event_loop.EnableUring(1024, IORING_SETUP_SINGLE_ISSUER); + } catch (...) { + FmtInfo(event_domain, + "Failed to initialize io_uring: {}", + std::current_exception()); + } +#endif } +#ifdef HAVE_URING + AtScopeExit(this) { + /* make sure that the Uring::Manager gets destructed + from within the EventThread, or else its + destruction in another thread will cause assertion + failures */ + event_loop.DisableUring(); + }; +#endif + event_loop.Run(); } diff --git a/src/event/Thread.hxx b/src/event/Thread.hxx index dda44db8e..0d1c94d0c 100644 --- a/src/event/Thread.hxx +++ b/src/event/Thread.hxx @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later // Copyright The Music Player Daemon Project -#ifndef MPD_EVENT_THREAD_HXX -#define MPD_EVENT_THREAD_HXX +#pragma once #include "Loop.hxx" #include "thread/Thread.hxx" @@ -36,5 +35,3 @@ public: private: void Run() noexcept; }; - -#endif /* MAIN_NOTIFY_H */