From ea2ced6b9f9f5b084a3db8a3b3d1a6f62a3d14d3 Mon Sep 17 00:00:00 2001 From: Max Kellermann <max.kellermann@gmail.com> Date: Wed, 29 Jan 2025 18:18:42 +0100 Subject: [PATCH] event/UringManager: replace with new Uring::Manager class From https://github.com/CM4all/libcommon - the new class is mostly identical, and I want to maintain only one of them. --- src/event/Loop.cxx | 2 +- src/event/UringManager.cxx | 39 ----------------------- src/event/UringManager.hxx | 29 ----------------- src/event/meson.build | 2 +- src/event/uring/Manager.cxx | 62 +++++++++++++++++++++++++++++++++++++ src/event/uring/Manager.hxx | 53 +++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 70 deletions(-) delete mode 100644 src/event/UringManager.cxx delete mode 100644 src/event/UringManager.hxx create mode 100644 src/event/uring/Manager.cxx create mode 100644 src/event/uring/Manager.hxx diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index 6d3cf7c2b..e89da24f4 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -12,7 +12,7 @@ #endif #ifdef HAVE_URING -#include "UringManager.hxx" +#include "uring/Manager.hxx" #include "util/PrintException.hxx" #include <stdio.h> #endif diff --git a/src/event/UringManager.cxx b/src/event/UringManager.cxx deleted file mode 100644 index 1baaf500e..000000000 --- a/src/event/UringManager.cxx +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The Music Player Daemon Project - -#include "UringManager.hxx" -#include "util/PrintException.hxx" - -namespace Uring { - -Manager::Manager(EventLoop &event_loop, - unsigned entries, unsigned flags) - :Queue(entries, flags), - event(event_loop, BIND_THIS_METHOD(OnSocketReady), - GetFileDescriptor()), - idle_event(event_loop, BIND_THIS_METHOD(OnIdle)) -{ - event.ScheduleRead(); -} - -void -Manager::OnSocketReady(unsigned) noexcept -{ - try { - DispatchCompletions(); - } catch (...) { - PrintException(std::current_exception()); - } -} - -void -Manager::OnIdle() noexcept -{ - try { - Queue::Submit(); - } catch (...) { - PrintException(std::current_exception()); - } -} - -} // namespace Uring diff --git a/src/event/UringManager.hxx b/src/event/UringManager.hxx deleted file mode 100644 index 4c4fc20bb..000000000 --- a/src/event/UringManager.hxx +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// Copyright The Music Player Daemon Project - -#pragma once - -#include "PipeEvent.hxx" -#include "IdleEvent.hxx" -#include "io/uring/Queue.hxx" - -namespace Uring { - -class Manager final : public Queue { - PipeEvent event; - IdleEvent idle_event; - -public: - explicit Manager(EventLoop &event_loop, - unsigned entries=1024, unsigned flags=0); - - void Submit() override { - idle_event.Schedule(); - } - -private: - void OnSocketReady(unsigned flags) noexcept; - void OnIdle() noexcept; -}; - -} // namespace Uring diff --git a/src/event/meson.build b/src/event/meson.build index b4d20f864..dc96289fe 100644 --- a/src/event/meson.build +++ b/src/event/meson.build @@ -8,7 +8,7 @@ configure_file(output: 'Features.h', configuration: event_features) event_sources = [] if uring_dep.found() - event_sources += 'UringManager.cxx' + event_sources += 'uring/Manager.cxx' endif if is_windows diff --git a/src/event/uring/Manager.cxx b/src/event/uring/Manager.cxx new file mode 100644 index 000000000..9f6353140 --- /dev/null +++ b/src/event/uring/Manager.cxx @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright CM4all GmbH +// author: Max Kellermann <mk@cm4all.com> + +#include "Manager.hxx" +#include "util/PrintException.hxx" + +namespace Uring { + +Manager::Manager(EventLoop &event_loop, + unsigned entries, unsigned flags) + :Queue(entries, flags), + event(event_loop, BIND_THIS_METHOD(OnReady), GetFileDescriptor()) +{ + event.ScheduleRead(); +} + +Manager::Manager(EventLoop &event_loop, + unsigned entries, struct io_uring_params ¶ms) + :Queue(entries, params), + event(event_loop, BIND_THIS_METHOD(OnReady), GetFileDescriptor()) +{ + event.ScheduleRead(); +} + +void +Manager::Submit() +{ + /* defer in "idle" mode to allow accumulation of more + events */ + defer_submit_event.ScheduleIdle(); +} + +void +Manager::DispatchCompletions() noexcept +{ + try { + Queue::DispatchCompletions(); + } catch (...) { + PrintException(std::current_exception()); + } + + CheckVolatileEvent(); +} + +inline void +Manager::OnReady(unsigned) noexcept +{ + DispatchCompletions(); +} + +void +Manager::DeferredSubmit() noexcept +{ + try { + Queue::Submit(); + } catch (...) { + PrintException(std::current_exception()); + } +} + +} // namespace Uring diff --git a/src/event/uring/Manager.hxx b/src/event/uring/Manager.hxx new file mode 100644 index 000000000..b03eafa30 --- /dev/null +++ b/src/event/uring/Manager.hxx @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright CM4all GmbH +// author: Max Kellermann <mk@cm4all.com> + +#pragma once + +#include "io/uring/Queue.hxx" +#include "event/DeferEvent.hxx" +#include "event/PipeEvent.hxx" + +namespace Uring { + +class Manager final : public Queue { + PipeEvent event; + + /** + * Responsible for invoking Queue::Submit() only once per + * #EventLoop iteration. + */ + DeferEvent defer_submit_event{GetEventLoop(), BIND_THIS_METHOD(DeferredSubmit)}; + + bool volatile_event = false; + +public: + explicit Manager(EventLoop &event_loop, + unsigned entries=1024, unsigned flags=0); + explicit Manager(EventLoop &event_loop, + unsigned entries, struct io_uring_params ¶ms); + + EventLoop &GetEventLoop() const noexcept { + return event.GetEventLoop(); + } + + void SetVolatile() noexcept { + volatile_event = true; + CheckVolatileEvent(); + } + + // virtual methods from class Uring::Queue + void Submit() override; + +private: + void CheckVolatileEvent() noexcept { + if (volatile_event && !HasPending()) + event.Cancel(); + } + + void DispatchCompletions() noexcept; + void OnReady(unsigned events) noexcept; + void DeferredSubmit() noexcept; +}; + +} // namespace Uring