From 5a4055fb08a1d38fd1e7c596f4d257d1656e6753 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 14 Oct 2020 14:24:16 +0200 Subject: [PATCH] event/SocketMonitor: refactor to SocketEvent Similar to commits 1686f4e857769650474498de40f12b13a5889ba1 and 30a5dd267b6cb9ee21106d5d949de2f04781c6e7 --- src/db/plugins/ProxyDatabasePlugin.cxx | 30 +++++++------- src/db/update/InotifySource.cxx | 16 ++++---- src/db/update/InotifySource.hxx | 10 +++-- src/event/BufferedSocket.cxx | 20 +++++----- src/event/BufferedSocket.hxx | 36 ++++++++++++----- src/event/FullyBufferedSocket.cxx | 16 ++++---- src/event/FullyBufferedSocket.hxx | 6 +-- src/event/Loop.cxx | 20 +++++----- src/event/Loop.hxx | 26 ++++++------- src/event/MultiSocketMonitor.hxx | 34 ++++++++-------- src/event/ServerSocket.cxx | 31 +++++++++------ src/event/SignalMonitor.cxx | 28 ++++++------- .../{SocketMonitor.cxx => SocketEvent.cxx} | 16 ++++---- .../{SocketMonitor.hxx => SocketEvent.hxx} | 35 ++++++++--------- src/event/UringManager.cxx | 4 +- src/event/UringManager.hxx | 13 ++++--- src/event/meson.build | 2 +- src/lib/curl/Global.cxx | 38 +++++++++++------- src/lib/dbus/Watch.cxx | 25 ++++++------ src/lib/dbus/Watch.hxx | 9 +++-- src/lib/nfs/Connection.cxx | 39 ++++++++----------- src/lib/nfs/Connection.hxx | 16 ++++---- src/output/plugins/httpd/HttpdClient.cxx | 19 ++++----- src/output/plugins/httpd/HttpdClient.hxx | 4 +- src/zeroconf/AvahiPoll.cxx | 31 +++++++-------- src/zeroconf/ZeroconfBonjour.cxx | 19 +++++---- 26 files changed, 282 insertions(+), 261 deletions(-) rename src/event/{SocketMonitor.cxx => SocketEvent.cxx} (88%) rename src/event/{SocketMonitor.hxx => SocketEvent.hxx} (87%) diff --git a/src/db/plugins/ProxyDatabasePlugin.cxx b/src/db/plugins/ProxyDatabasePlugin.cxx index b8c422928..3debf487c 100644 --- a/src/db/plugins/ProxyDatabasePlugin.cxx +++ b/src/db/plugins/ProxyDatabasePlugin.cxx @@ -42,7 +42,7 @@ #include "util/ScopeExit.hxx" #include "util/RuntimeError.hxx" #include "protocol/Ack.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "event/IdleEvent.hxx" #include "Log.hxx" @@ -85,7 +85,8 @@ public: } }; -class ProxyDatabase final : public Database, SocketMonitor { +class ProxyDatabase final : public Database { + SocketEvent socket_event; IdleEvent idle_event; DatabaseListener &listener; @@ -149,10 +150,8 @@ private: void Disconnect() noexcept; + void OnSocketReady(unsigned flags) noexcept; void OnIdle() noexcept; - - /* virtual methods from SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override; }; static constexpr struct { @@ -446,7 +445,7 @@ SendGroup(mpd_connection *connection, ConstBuffer group) ProxyDatabase::ProxyDatabase(EventLoop &_loop, DatabaseListener &_listener, const ConfigBlock &block) :Database(proxy_db_plugin), - SocketMonitor(_loop), + socket_event(_loop, BIND_THIS_METHOD(OnSocketReady)), idle_event(_loop, BIND_THIS_METHOD(OnIdle)), listener(_listener), host(block.GetBlockValue("host", "")), @@ -527,7 +526,7 @@ ProxyDatabase::Connect() idle_received = ~0U; is_idle = false; - SocketMonitor::Open(SocketDescriptor(mpd_async_get_fd(mpd_connection_get_async(connection)))); + socket_event.Open(SocketDescriptor(mpd_async_get_fd(mpd_connection_get_async(connection)))); idle_event.Schedule(); } @@ -574,13 +573,13 @@ ProxyDatabase::Disconnect() noexcept assert(connection != nullptr); idle_event.Cancel(); - SocketMonitor::Steal(); + socket_event.Steal(); mpd_connection_free(connection); connection = nullptr; } -bool +void ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept { assert(connection != nullptr); @@ -588,8 +587,8 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept if (!is_idle) { // TODO: can this happen? idle_event.Schedule(); - SocketMonitor::Cancel(); - return true; + socket_event.Cancel(); + return; } auto idle = (unsigned)mpd_recv_idle(connection, false); @@ -599,7 +598,7 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept } catch (...) { LogError(std::current_exception()); Disconnect(); - return false; + return; } } @@ -607,8 +606,7 @@ ProxyDatabase::OnSocketReady([[maybe_unused]] unsigned flags) noexcept idle_received |= idle; is_idle = false; idle_event.Schedule(); - SocketMonitor::Cancel(); - return true; + socket_event.Cancel(); } void @@ -636,14 +634,14 @@ ProxyDatabase::OnIdle() noexcept LogError(std::current_exception()); } - SocketMonitor::Steal(); + socket_event.Steal(); mpd_connection_free(connection); connection = nullptr; return; } is_idle = true; - SocketMonitor::ScheduleRead(); + socket_event.ScheduleRead(); } const LightSong * diff --git a/src/db/update/InotifySource.cxx b/src/db/update/InotifySource.cxx index fb35adeb5..e7caa84c7 100644 --- a/src/db/update/InotifySource.cxx +++ b/src/db/update/InotifySource.cxx @@ -30,14 +30,14 @@ #include -bool +void InotifySource::OnSocketReady([[maybe_unused]] unsigned flags) noexcept { uint8_t buffer[4096]; static_assert(sizeof(buffer) >= sizeof(struct inotify_event) + NAME_MAX + 1, "inotify buffer too small"); - auto ifd = GetSocket().ToFileDescriptor(); + auto ifd = socket_event.GetSocket().ToFileDescriptor(); ssize_t nbytes = ifd.Read(buffer, sizeof(buffer)); if (nbytes < 0) FatalSystemError("Failed to read from inotify"); @@ -63,8 +63,6 @@ InotifySource::OnSocketReady([[maybe_unused]] unsigned flags) noexcept callback(event->wd, event->mask, name, callback_ctx); p += sizeof(*event) + event->len; } - - return true; } static FileDescriptor @@ -79,17 +77,17 @@ InotifyInit() InotifySource::InotifySource(EventLoop &_loop, mpd_inotify_callback_t _callback, void *_ctx) - :SocketMonitor(SocketDescriptor::FromFileDescriptor(InotifyInit()), - _loop), + :socket_event(_loop, BIND_THIS_METHOD(OnSocketReady), + SocketDescriptor::FromFileDescriptor(InotifyInit())), callback(_callback), callback_ctx(_ctx) { - ScheduleRead(); + socket_event.ScheduleRead(); } int InotifySource::Add(const char *path_fs, unsigned mask) { - auto ifd = GetSocket().ToFileDescriptor(); + auto ifd = socket_event.GetSocket().ToFileDescriptor(); int wd = inotify_add_watch(ifd.Get(), path_fs, mask); if (wd < 0) throw MakeErrno("inotify_add_watch() has failed"); @@ -100,7 +98,7 @@ InotifySource::Add(const char *path_fs, unsigned mask) void InotifySource::Remove(unsigned wd) noexcept { - auto ifd = GetSocket().ToFileDescriptor(); + auto ifd = socket_event.GetSocket().ToFileDescriptor(); int ret = inotify_rm_watch(ifd.Get(), wd); if (ret < 0 && errno != EINVAL) LogErrno(inotify_domain, "inotify_rm_watch() has failed"); diff --git a/src/db/update/InotifySource.hxx b/src/db/update/InotifySource.hxx index 373425496..256100f06 100644 --- a/src/db/update/InotifySource.hxx +++ b/src/db/update/InotifySource.hxx @@ -20,12 +20,14 @@ #ifndef MPD_INOTIFY_SOURCE_HXX #define MPD_INOTIFY_SOURCE_HXX -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, const char *name, void *ctx); -class InotifySource final : private SocketMonitor { +class InotifySource final { + SocketEvent socket_event; + mpd_inotify_callback_t callback; void *callback_ctx; @@ -43,7 +45,7 @@ public: mpd_inotify_callback_t callback, void *ctx); ~InotifySource() noexcept { - Close(); + socket_event.Close(); } /** @@ -63,7 +65,7 @@ public: void Remove(unsigned wd) noexcept; private: - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; }; #endif diff --git a/src/event/BufferedSocket.cxx b/src/event/BufferedSocket.cxx index 5ad98d3aa..5ee8e396b 100644 --- a/src/event/BufferedSocket.cxx +++ b/src/event/BufferedSocket.cxx @@ -69,7 +69,7 @@ BufferedSocket::ResumeInput() noexcept while (true) { const auto buffer = input.Read(); if (buffer.empty()) { - ScheduleRead(); + event.ScheduleRead(); return true; } @@ -81,11 +81,11 @@ BufferedSocket::ResumeInput() noexcept return false; } - ScheduleRead(); + event.ScheduleRead(); return true; case InputResult::PAUSE: - CancelRead(); + event.CancelRead(); return true; case InputResult::AGAIN: @@ -97,25 +97,23 @@ BufferedSocket::ResumeInput() noexcept } } -bool +void BufferedSocket::OnSocketReady(unsigned flags) noexcept { assert(IsDefined()); - if (gcc_unlikely(flags & (ERROR|HANGUP))) { + if (gcc_unlikely(flags & (SocketEvent::ERROR|SocketEvent::HANGUP))) { OnSocketClosed(); - return false; + return; } - if (flags & READ) { + if (flags & SocketEvent::READ) { assert(!input.IsFull()); if (!ReadToBuffer() || !ResumeInput()) - return false; + return; if (!input.IsFull()) - ScheduleRead(); + event.ScheduleRead(); } - - return true; } diff --git a/src/event/BufferedSocket.hxx b/src/event/BufferedSocket.hxx index 484ea9b5b..e5d9b31bc 100644 --- a/src/event/BufferedSocket.hxx +++ b/src/event/BufferedSocket.hxx @@ -20,7 +20,7 @@ #ifndef MPD_BUFFERED_SOCKET_HXX #define MPD_BUFFERED_SOCKET_HXX -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "util/StaticFifoBuffer.hxx" #include @@ -30,20 +30,37 @@ class EventLoop; /** - * A #SocketMonitor specialization that adds an input buffer. + * A #SocketEvent specialization that adds an input buffer. */ -class BufferedSocket : protected SocketMonitor { +class BufferedSocket { StaticFifoBuffer input; +protected: + SocketEvent event; + public: + using ssize_t = SocketEvent::ssize_t; + BufferedSocket(SocketDescriptor _fd, EventLoop &_loop) noexcept - :SocketMonitor(_fd, _loop) { - ScheduleRead(); + :event(_loop, BIND_THIS_METHOD(OnSocketReady), _fd) { + event.ScheduleRead(); } - using SocketMonitor::GetEventLoop; - using SocketMonitor::IsDefined; - using SocketMonitor::Close; + auto &GetEventLoop() const noexcept { + return event.GetEventLoop(); + } + + bool IsDefined() const noexcept { + return event.IsDefined(); + } + + auto GetSocket() const noexcept { + return event.GetSocket(); + } + + void Close() noexcept { + event.Close(); + } private: /** @@ -116,8 +133,7 @@ protected: virtual void OnSocketError(std::exception_ptr ep) noexcept = 0; virtual void OnSocketClosed() noexcept = 0; - /* virtual methods from class SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override; + virtual void OnSocketReady(unsigned flags) noexcept; }; #endif diff --git a/src/event/FullyBufferedSocket.cxx b/src/event/FullyBufferedSocket.cxx index 9b5eb3c55..d1a1b00d5 100644 --- a/src/event/FullyBufferedSocket.cxx +++ b/src/event/FullyBufferedSocket.cxx @@ -35,7 +35,7 @@ FullyBufferedSocket::DirectWrite(const void *data, size_t length) noexcept return 0; idle_event.Cancel(); - BufferedSocket::Cancel(); + event.Cancel(); if (IsSocketErrorClosed(code)) OnSocketClosed(); @@ -54,7 +54,7 @@ FullyBufferedSocket::Flush() noexcept const auto data = output.Read(); if (data.empty()) { idle_event.Cancel(); - CancelWrite(); + event.CancelWrite(); return true; } @@ -66,7 +66,7 @@ FullyBufferedSocket::Flush() noexcept if (output.empty()) { idle_event.Cancel(); - CancelWrite(); + event.CancelWrite(); } return true; @@ -92,23 +92,23 @@ FullyBufferedSocket::Write(const void *data, size_t length) noexcept return true; } -bool +void FullyBufferedSocket::OnSocketReady(unsigned flags) noexcept { - if (flags & WRITE) { + if (flags & SocketEvent::WRITE) { assert(!output.empty()); assert(!idle_event.IsActive()); if (!Flush()) - return false; + return; } - return BufferedSocket::OnSocketReady(flags); + BufferedSocket::OnSocketReady(flags); } void FullyBufferedSocket::OnIdle() noexcept { if (Flush() && !output.empty()) - ScheduleWrite(); + event.ScheduleWrite(); } diff --git a/src/event/FullyBufferedSocket.hxx b/src/event/FullyBufferedSocket.hxx index 2642ec705..1da0f8c89 100644 --- a/src/event/FullyBufferedSocket.hxx +++ b/src/event/FullyBufferedSocket.hxx @@ -69,10 +69,10 @@ protected: */ bool Write(const void *data, size_t length) noexcept; - /* virtual methods from class SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override; - void OnIdle() noexcept; + + /* virtual methods from class BufferedSocket */ + void OnSocketReady(unsigned flags) noexcept override; }; #endif diff --git a/src/event/Loop.cxx b/src/event/Loop.cxx index 49530920e..e6256a517 100644 --- a/src/event/Loop.cxx +++ b/src/event/Loop.cxx @@ -19,7 +19,7 @@ #include "Loop.hxx" #include "TimerEvent.hxx" -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "IdleEvent.hxx" #include "util/ScopeExit.hxx" @@ -47,7 +47,7 @@ EventLoop::EventLoop( ) : #ifdef HAVE_THREADED_EVENT_LOOP - SocketMonitor(*this), + wake_event(*this, BIND_THIS_METHOD(OnSocketReady)), thread(_thread), /* if this instance is hosted by an EventThread (no ThreadId known yet) then we're not yet alive until the thread is @@ -59,7 +59,7 @@ EventLoop::EventLoop( quit(false) { #ifdef HAVE_THREADED_EVENT_LOOP - SocketMonitor::Open(SocketDescriptor(wake_fd.Get())); + wake_event.Open(SocketDescriptor(wake_fd.Get())); #endif } @@ -198,7 +198,7 @@ EventLoop::Run() noexcept assert(alive); assert(busy); - SocketMonitor::Schedule(SocketMonitor::READ); + wake_event.Schedule(SocketEvent::READ); #endif #ifdef HAVE_URING @@ -214,7 +214,7 @@ EventLoop::Run() noexcept #ifdef HAVE_THREADED_EVENT_LOOP AtScopeExit(this) { - SocketMonitor::Cancel(); + wake_event.Cancel(); }; #endif @@ -262,9 +262,9 @@ EventLoop::Run() noexcept ready_sockets.clear(); for (size_t i = 0; i < poll_result.GetSize(); ++i) { - auto &sm = *(SocketMonitor *)poll_result.GetObject(i); - sm.SetReadyFlags(poll_result.GetEvents(i)); - ready_sockets.push_back(sm); + auto &s = *(SocketEvent *)poll_result.GetObject(i); + s.SetReadyFlags(poll_result.GetEvents(i)); + ready_sockets.push_back(s); } now = std::chrono::steady_clock::now(); @@ -339,7 +339,7 @@ EventLoop::HandleDeferred() noexcept } } -bool +void EventLoop::OnSocketReady([[maybe_unused]] unsigned flags) noexcept { assert(IsInside()); @@ -348,8 +348,6 @@ EventLoop::OnSocketReady([[maybe_unused]] unsigned flags) noexcept const std::lock_guard lock(mutex); HandleDeferred(); - - return true; } #endif diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 257979845..15c788a92 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -22,7 +22,7 @@ #include "Chrono.hxx" #include "PollGroup.hxx" -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "event/Features.h" #include "util/Compiler.h" @@ -56,15 +56,13 @@ class DeferEvent; * thread that runs it, except where explicitly documented as * thread-safe. * - * @see SocketMonitor, MultiSocketMonitor, TimerEvent, IdleEvent + * @see SocketEvent, MultiSocketMonitor, TimerEvent, IdleEvent */ class EventLoop final -#ifdef HAVE_THREADED_EVENT_LOOP - : SocketMonitor -#endif { #ifdef HAVE_THREADED_EVENT_LOOP WakeFD wake_fd; + SocketEvent wake_event; #endif struct TimerCompare { @@ -96,14 +94,14 @@ class EventLoop final #endif using ReadySocketList = - boost::intrusive::list, + boost::intrusive::list, boost::intrusive::constant_time_size>; /** - * A linked list of #SocketMonitor instances which have a + * A linked list of #SocketEvent instances which have a * non-zero "ready_flags" field, and need to be dispatched. */ ReadySocketList ready_sockets; @@ -190,7 +188,7 @@ public: */ void Break() noexcept; - bool AddFD(int _fd, unsigned flags, SocketMonitor &m) noexcept { + bool AddFD(int _fd, unsigned flags, SocketEvent &m) noexcept { #ifdef HAVE_THREADED_EVENT_LOOP assert(!IsAlive() || IsInside()); #endif @@ -198,7 +196,7 @@ public: return poll_group.Add(_fd, flags, &m); } - bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) noexcept { + bool ModifyFD(int _fd, unsigned flags, SocketEvent &m) noexcept { #ifdef HAVE_THREADED_EVENT_LOOP assert(!IsAlive() || IsInside()); #endif @@ -207,7 +205,7 @@ public: } /** - * Remove the given #SocketMonitor after the file descriptor + * Remove the given #SocketEvent after the file descriptor * has been closed. This is like RemoveFD(), but does not * attempt to use #EPOLL_CTL_DEL. */ @@ -261,7 +259,7 @@ private: Event::Duration HandleTimers() noexcept; #ifdef HAVE_THREADED_EVENT_LOOP - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; #endif public: diff --git a/src/event/MultiSocketMonitor.hxx b/src/event/MultiSocketMonitor.hxx index f15940f96..703bcb47e 100644 --- a/src/event/MultiSocketMonitor.hxx +++ b/src/event/MultiSocketMonitor.hxx @@ -22,7 +22,7 @@ #include "IdleEvent.hxx" #include "TimerEvent.hxx" -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "event/Features.h" #include @@ -36,35 +36,43 @@ struct pollfd; class EventLoop; /** - * Similar to #SocketMonitor, but monitors multiple sockets. To use + * Similar to #SocketEvent, but monitors multiple sockets. To use * it, implement the methods PrepareSockets() and DispatchSockets(). * In PrepareSockets(), use UpdateSocketList() and AddSocket(). * DispatchSockets() will be called if at least one socket is ready. */ class MultiSocketMonitor { - class SingleFD final : public SocketMonitor { + class SingleFD final { MultiSocketMonitor &multi; + SocketEvent event; + unsigned revents; public: SingleFD(MultiSocketMonitor &_multi, SocketDescriptor _fd) noexcept - :SocketMonitor(_fd, _multi.GetEventLoop()), - multi(_multi), revents(0) {} + :multi(_multi), + event(multi.GetEventLoop(), + BIND_THIS_METHOD(OnSocketReady), _fd), + revents(0) {} SocketDescriptor GetSocket() const noexcept { - return SocketMonitor::GetSocket(); + return event.GetSocket(); } unsigned GetEvents() const noexcept { - return SocketMonitor::GetScheduledFlags(); + return event.GetScheduledFlags(); } void SetEvents(unsigned _events) noexcept { revents &= _events; - SocketMonitor::Schedule(_events); + event.Schedule(_events); + } + + bool Schedule(unsigned events) noexcept { + return event.Schedule(events); } unsigned GetReturnedEvents() const noexcept { @@ -75,11 +83,10 @@ class MultiSocketMonitor revents = 0; } - protected: - bool OnSocketReady(unsigned flags) noexcept override { + private: + void OnSocketReady(unsigned flags) noexcept { revents = flags; multi.SetReady(); - return true; } }; @@ -119,11 +126,6 @@ class MultiSocketMonitor #endif public: - static constexpr unsigned READ = SocketMonitor::READ; - static constexpr unsigned WRITE = SocketMonitor::WRITE; - static constexpr unsigned ERROR = SocketMonitor::ERROR; - static constexpr unsigned HANGUP = SocketMonitor::HANGUP; - MultiSocketMonitor(EventLoop &_loop) noexcept; EventLoop &GetEventLoop() const noexcept { diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx index 35407edb7..cfdbd41bd 100644 --- a/src/event/ServerSocket.cxx +++ b/src/event/ServerSocket.cxx @@ -29,7 +29,7 @@ #include "net/Resolver.hxx" #include "net/AddressInfo.hxx" #include "net/ToString.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "fs/AllocatedPath.hxx" #include "util/RuntimeError.hxx" #include "util/Domain.hxx" @@ -43,9 +43,11 @@ #include #endif -class ServerSocket::OneServerSocket final : private SocketMonitor { +class ServerSocket::OneServerSocket final { ServerSocket &parent; + SocketEvent event; + const unsigned serial; #ifdef HAVE_UN @@ -59,8 +61,9 @@ public: OneServerSocket(EventLoop &_loop, ServerSocket &_parent, unsigned _serial, A &&_address) noexcept - :SocketMonitor(_loop), - parent(_parent), serial(_serial), + :parent(_parent), + event(_loop, BIND_THIS_METHOD(OnSocketReady)), + serial(_serial), #ifdef HAVE_UN path(nullptr), #endif @@ -88,10 +91,15 @@ public: } #endif + bool IsDefined() const noexcept { + return event.IsDefined(); + } + void Open(); - using SocketMonitor::IsDefined; - using SocketMonitor::Close; + void Close() noexcept { + event.Close(); + } [[nodiscard]] gcc_pure std::string ToString() const noexcept { @@ -99,14 +107,14 @@ public: } void SetFD(UniqueSocketDescriptor _fd) noexcept { - SocketMonitor::Open(_fd.Release()); - SocketMonitor::ScheduleRead(); + event.Open(_fd.Release()); + event.ScheduleRead(); } void Accept() noexcept; private: - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; }; static constexpr Domain server_socket_domain("server_socket"); @@ -140,7 +148,7 @@ inline void ServerSocket::OneServerSocket::Accept() noexcept { StaticSocketAddress peer_address; - UniqueSocketDescriptor peer_fd(GetSocket().AcceptNonBlock(peer_address)); + UniqueSocketDescriptor peer_fd(event.GetSocket().AcceptNonBlock(peer_address)); if (!peer_fd.IsDefined()) { const SocketErrorMessage msg; FormatError(server_socket_domain, @@ -160,11 +168,10 @@ ServerSocket::OneServerSocket::Accept() noexcept parent.OnAccept(std::move(peer_fd), peer_address, uid); } -bool +void ServerSocket::OneServerSocket::OnSocketReady([[maybe_unused]] unsigned flags) noexcept { Accept(); - return true; } inline void diff --git a/src/event/SignalMonitor.cxx b/src/event/SignalMonitor.cxx index f864c9a4e..1202f4408 100644 --- a/src/event/SignalMonitor.cxx +++ b/src/event/SignalMonitor.cxx @@ -22,7 +22,7 @@ #ifndef _WIN32 -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "util/Manual.hxx" #include "system/Error.hxx" @@ -44,33 +44,37 @@ #include #endif -class SignalMonitor final : private SocketMonitor { +class SignalMonitor final { #ifdef USE_SIGNALFD SignalFD fd; #else WakeFD fd; #endif + SocketEvent event; + public: explicit SignalMonitor(EventLoop &_loop) - :SocketMonitor(_loop) { + :event(_loop, BIND_THIS_METHOD(OnSocketReady)) { #ifndef USE_SIGNALFD - SocketMonitor::Open(SocketDescriptor(fd.Get())); - SocketMonitor::ScheduleRead(); + event.Open(SocketDescriptor(fd.Get())); + event.ScheduleRead(); #endif } - using SocketMonitor::GetEventLoop; + auto &GetEventLoop() const noexcept { + return event.GetEventLoop(); + } #ifdef USE_SIGNALFD void Update(sigset_t &mask) noexcept { - const bool was_open = SocketMonitor::IsDefined(); + const bool was_open = event.IsDefined(); fd.Create(mask); if (!was_open) { - SocketMonitor::Open(SocketDescriptor(fd.Get())); - SocketMonitor::ScheduleRead(); + event.Open(SocketDescriptor(fd.Get())); + event.ScheduleRead(); } } #else @@ -80,7 +84,7 @@ public: #endif private: - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; }; /* this should be enough - is it? */ @@ -195,7 +199,7 @@ SignalMonitorRegister(int signo, SignalHandler handler) #endif } -bool +void SignalMonitor::OnSocketReady(unsigned) noexcept { #ifdef USE_SIGNALFD @@ -213,8 +217,6 @@ SignalMonitor::OnSocketReady(unsigned) noexcept if (signal_pending[i].exchange(false)) signal_handlers[i](); #endif - - return true; } #endif diff --git a/src/event/SocketMonitor.cxx b/src/event/SocketEvent.cxx similarity index 88% rename from src/event/SocketMonitor.cxx rename to src/event/SocketEvent.cxx index 661689e14..acea03d53 100644 --- a/src/event/SocketMonitor.cxx +++ b/src/event/SocketEvent.cxx @@ -17,7 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "Loop.hxx" #include "event/Features.h" @@ -29,23 +29,23 @@ #endif void -SocketMonitor::Dispatch() noexcept +SocketEvent::Dispatch() noexcept { const unsigned flags = std::exchange(ready_flags, 0) & (GetScheduledFlags() | IMPLICIT_FLAGS); if (flags != 0) - OnSocketReady(flags); + callback(flags); } -SocketMonitor::~SocketMonitor() noexcept +SocketEvent::~SocketEvent() noexcept { if (IsDefined()) Cancel(); } void -SocketMonitor::Open(SocketDescriptor _fd) noexcept +SocketEvent::Open(SocketDescriptor _fd) noexcept { assert(!fd.IsDefined()); assert(_fd.IsDefined()); @@ -54,7 +54,7 @@ SocketMonitor::Open(SocketDescriptor _fd) noexcept } SocketDescriptor -SocketMonitor::Steal() noexcept +SocketEvent::Steal() noexcept { assert(IsDefined()); @@ -64,13 +64,13 @@ SocketMonitor::Steal() noexcept } void -SocketMonitor::Close() noexcept +SocketEvent::Close() noexcept { Steal().Close(); } bool -SocketMonitor::Schedule(unsigned flags) noexcept +SocketEvent::Schedule(unsigned flags) noexcept { assert(IsDefined()); diff --git a/src/event/SocketMonitor.hxx b/src/event/SocketEvent.hxx similarity index 87% rename from src/event/SocketMonitor.hxx rename to src/event/SocketEvent.hxx index 881877a88..27b6cdd6f 100644 --- a/src/event/SocketMonitor.hxx +++ b/src/event/SocketEvent.hxx @@ -17,11 +17,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef MPD_SOCKET_MONITOR_HXX -#define MPD_SOCKET_MONITOR_HXX +#ifndef MPD_SOCKET_EVENT_HXX +#define MPD_SOCKET_EVENT_HXX #include "PollGroup.hxx" #include "net/SocketDescriptor.hxx" +#include "util/BindMethod.hxx" #include @@ -34,8 +35,8 @@ class EventLoop; /** * Monitor events on a socket. Call Schedule() to announce events * you're interested in, or Cancel() to cancel your subscription. The - * #EventLoop will invoke virtual method OnSocketReady() as soon as - * any of the subscribed events are ready. + * #EventLoop will invoke the callback as soon as any of the + * subscribed events are ready. * * This class does not feel responsible for closing the socket. Call * Close() to do it manually. @@ -44,14 +45,18 @@ class EventLoop; * thread that runs the #EventLoop, except where explicitly documented * as thread-safe. */ -class SocketMonitor { +class SocketEvent { friend class EventLoop; + EventLoop &loop; + using ReadyListHook = boost::intrusive::list_member_hook>; ReadyListHook ready_siblings; + using Callback = BoundMethod; + const Callback callback; + SocketDescriptor fd = SocketDescriptor::Undefined(); - EventLoop &loop; /** * A bit mask of events that is currently registered in the @@ -80,13 +85,13 @@ public: typedef std::make_signed::type ssize_t; - explicit SocketMonitor(EventLoop &_loop) noexcept - :loop(_loop) {} + SocketEvent(EventLoop &_loop, Callback _callback, + SocketDescriptor _fd=SocketDescriptor::Undefined()) noexcept + :loop(_loop), + callback(_callback), + fd(_fd) {} - SocketMonitor(SocketDescriptor _fd, EventLoop &_loop) noexcept - :fd(_fd), loop(_loop) {} - - ~SocketMonitor() noexcept; + ~SocketEvent() noexcept; auto &GetEventLoop() const noexcept { return loop; @@ -148,12 +153,6 @@ public: Schedule(GetScheduledFlags() & ~WRITE); } -protected: - /** - * @return false if the socket has been closed - */ - virtual bool OnSocketReady(unsigned flags) noexcept = 0; - public: void Dispatch() noexcept; }; diff --git a/src/event/UringManager.cxx b/src/event/UringManager.cxx index 9bb9ab48d..5c8ca9471 100644 --- a/src/event/UringManager.cxx +++ b/src/event/UringManager.cxx @@ -22,15 +22,13 @@ namespace Uring { -bool +void Manager::OnSocketReady(unsigned) noexcept { try { DispatchCompletions(); - return true; } catch (...) { PrintException(std::current_exception()); - return false; } } diff --git a/src/event/UringManager.hxx b/src/event/UringManager.hxx index 8afef7cfe..8371503c5 100644 --- a/src/event/UringManager.hxx +++ b/src/event/UringManager.hxx @@ -19,23 +19,24 @@ #pragma once -#include "SocketMonitor.hxx" +#include "SocketEvent.hxx" #include "IdleEvent.hxx" #include "io/uring/Queue.hxx" namespace Uring { -class Manager final : public Queue, SocketMonitor { +class Manager final : public Queue { + SocketEvent event; IdleEvent idle_event; public: explicit Manager(EventLoop &event_loop) :Queue(1024, 0), - SocketMonitor(SocketDescriptor::FromFileDescriptor(GetFileDescriptor()), - event_loop), + event(event_loop, BIND_THIS_METHOD(OnSocketReady), + SocketDescriptor::FromFileDescriptor(GetFileDescriptor())), idle_event(event_loop, BIND_THIS_METHOD(OnIdle)) { - SocketMonitor::ScheduleRead(); + event.ScheduleRead(); } void Push(struct io_uring_sqe &sqe, @@ -45,7 +46,7 @@ public: } private: - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; void OnIdle() noexcept; }; diff --git a/src/event/meson.build b/src/event/meson.build index 556232cad..5331d67af 100644 --- a/src/event/meson.build +++ b/src/event/meson.build @@ -26,7 +26,7 @@ event = static_library( 'IdleEvent.cxx', 'DeferEvent.cxx', 'MaskMonitor.cxx', - 'SocketMonitor.cxx', + 'SocketEvent.cxx', 'BufferedSocket.cxx', 'FullyBufferedSocket.cxx', 'MultiSocketMonitor.cxx', diff --git a/src/lib/curl/Global.cxx b/src/lib/curl/Global.cxx index 8b32eae97..e7ee47182 100644 --- a/src/lib/curl/Global.cxx +++ b/src/lib/curl/Global.cxx @@ -31,7 +31,7 @@ #include "Request.hxx" #include "Log.hxx" #include "event/Loop.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "util/RuntimeError.hxx" #include "util/Domain.hxx" @@ -42,12 +42,15 @@ static constexpr Domain curlm_domain("curlm"); /** * Monitor for one socket created by CURL. */ -class CurlSocket final : SocketMonitor { +class CurlSocket final { CurlGlobal &global; + SocketEvent socket_event; + public: CurlSocket(CurlGlobal &_global, EventLoop &_loop, SocketDescriptor _fd) - :SocketMonitor(_fd, _loop), global(_global) {} + :global(_global), + socket_event(_loop, BIND_THIS_METHOD(OnSocketReady), _fd) {} ~CurlSocket() noexcept { /* TODO: sometimes, CURL uses CURL_POLL_REMOVE after @@ -59,6 +62,10 @@ public: better solution? */ } + auto &GetEventLoop() const noexcept { + return socket_event.GetEventLoop(); + } + /** * Callback function for CURLMOPT_SOCKETFUNCTION. */ @@ -66,13 +73,17 @@ public: curl_socket_t s, int action, void *userp, void *socketp) noexcept; - bool OnSocketReady(unsigned flags) noexcept override; - private: + SocketDescriptor GetSocket() const noexcept { + return socket_event.GetSocket(); + } + + void OnSocketReady(unsigned flags) noexcept; + static constexpr int FlagsToCurlCSelect(unsigned flags) noexcept { - return (flags & (READ | HANGUP) ? CURL_CSELECT_IN : 0) | - (flags & WRITE ? CURL_CSELECT_OUT : 0) | - (flags & ERROR ? CURL_CSELECT_ERR : 0); + return (flags & (SocketEvent::READ | SocketEvent::HANGUP) ? CURL_CSELECT_IN : 0) | + (flags & SocketEvent::WRITE ? CURL_CSELECT_OUT : 0) | + (flags & SocketEvent::ERROR ? CURL_CSELECT_ERR : 0); } gcc_const @@ -82,13 +93,13 @@ private: return 0; case CURL_POLL_IN: - return READ; + return SocketEvent::READ; case CURL_POLL_OUT: - return WRITE; + return SocketEvent::WRITE; case CURL_POLL_INOUT: - return READ|WRITE; + return SocketEvent::READ|SocketEvent::WRITE; } assert(false); @@ -130,17 +141,16 @@ CurlSocket::SocketFunction([[maybe_unused]] CURL *easy, unsigned flags = CurlPollToFlags(action); if (flags != 0) - cs->Schedule(flags); + cs->socket_event.Schedule(flags); return 0; } -bool +void CurlSocket::OnSocketReady(unsigned flags) noexcept { assert(GetEventLoop().IsInside()); global.SocketAction(GetSocket().Get(), FlagsToCurlCSelect(flags)); - return true; } void diff --git a/src/lib/dbus/Watch.cxx b/src/lib/dbus/Watch.cxx index a399836a7..2e6892a48 100644 --- a/src/lib/dbus/Watch.cxx +++ b/src/lib/dbus/Watch.cxx @@ -1,5 +1,5 @@ /* - * Copyright 2007-2018 Content Management AG + * Copyright 2007-2020 CM4all GmbH * All rights reserved. * * author: Max Kellermann @@ -36,8 +36,8 @@ namespace ODBus { WatchManager::Watch::Watch(EventLoop &event_loop, WatchManager &_parent, DBusWatch &_watch) noexcept - :SocketMonitor(event_loop), - parent(_parent), watch(_watch) + :parent(_parent), watch(_watch), + event(event_loop, BIND_THIS_METHOD(OnSocketReady)) { Toggled(); } @@ -45,30 +45,30 @@ WatchManager::Watch::Watch(EventLoop &event_loop, static constexpr unsigned DbusToLibevent(unsigned flags) noexcept { - return ((flags & DBUS_WATCH_READABLE) != 0) * SocketMonitor::READ | - ((flags & DBUS_WATCH_WRITABLE) != 0) * SocketMonitor::WRITE; + return ((flags & DBUS_WATCH_READABLE) != 0) * SocketEvent::READ | + ((flags & DBUS_WATCH_WRITABLE) != 0) * SocketEvent::WRITE; } void WatchManager::Watch::Toggled() noexcept { - if (SocketMonitor::IsDefined()) - SocketMonitor::Cancel(); + if (event.IsDefined()) + event.Cancel(); if (dbus_watch_get_enabled(&watch)) { - SocketMonitor::Open(SocketDescriptor(dbus_watch_get_unix_fd(&watch))); - SocketMonitor::Schedule(DbusToLibevent(dbus_watch_get_flags(&watch))); + event.Open(SocketDescriptor(dbus_watch_get_unix_fd(&watch))); + event.Schedule(DbusToLibevent(dbus_watch_get_flags(&watch))); } } static constexpr unsigned LibeventToDbus(unsigned flags) noexcept { - return ((flags & SocketMonitor::READ) != 0) * DBUS_WATCH_READABLE | - ((flags & SocketMonitor::WRITE) != 0) * DBUS_WATCH_WRITABLE; + return ((flags & SocketEvent::READ) != 0) * DBUS_WATCH_READABLE | + ((flags & SocketEvent::WRITE) != 0) * DBUS_WATCH_WRITABLE; } -bool +void WatchManager::Watch::OnSocketReady(unsigned events) noexcept { /* copy the "parent" reference to the stack, because the @@ -79,7 +79,6 @@ WatchManager::Watch::OnSocketReady(unsigned events) noexcept dbus_watch_handle(&watch, LibeventToDbus(events)); _parent.ScheduleDispatch(); - return true; } void diff --git a/src/lib/dbus/Watch.hxx b/src/lib/dbus/Watch.hxx index 351ce46f9..afce69a16 100644 --- a/src/lib/dbus/Watch.hxx +++ b/src/lib/dbus/Watch.hxx @@ -1,5 +1,5 @@ /* - * Copyright 2007-2018 Content Management AG + * Copyright 2007-2020 CM4all GmbH * All rights reserved. * * author: Max Kellermann @@ -34,7 +34,7 @@ #define ODBUS_WATCH_HXX #include "Connection.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "event/DeferEvent.hxx" #include @@ -58,9 +58,10 @@ class WatchManager { Connection connection; - class Watch final : SocketMonitor { + class Watch { WatchManager &parent; DBusWatch &watch; + SocketEvent event; public: Watch(EventLoop &event_loop, WatchManager &_parent, @@ -69,7 +70,7 @@ class WatchManager { void Toggled() noexcept; private: - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; }; std::map watches; diff --git a/src/lib/nfs/Connection.cxx b/src/lib/nfs/Connection.cxx index 933b67cc3..9b546f941 100644 --- a/src/lib/nfs/Connection.cxx +++ b/src/lib/nfs/Connection.cxx @@ -183,17 +183,17 @@ NfsConnection::CancellableCallback::Callback(int err, static constexpr unsigned libnfs_to_events(int i) noexcept { - return ((i & POLLIN) ? SocketMonitor::READ : 0) | - ((i & POLLOUT) ? SocketMonitor::WRITE : 0); + return ((i & POLLIN) ? SocketEvent::READ : 0) | + ((i & POLLOUT) ? SocketEvent::WRITE : 0); } static constexpr int events_to_libnfs(unsigned i) noexcept { - return ((i & SocketMonitor::READ) ? POLLIN : 0) | - ((i & SocketMonitor::WRITE) ? POLLOUT : 0) | - ((i & SocketMonitor::HANGUP) ? POLLHUP : 0) | - ((i & SocketMonitor::ERROR) ? POLLERR : 0); + return ((i & SocketEvent::READ) ? POLLIN : 0) | + ((i & SocketEvent::WRITE) ? POLLOUT : 0) | + ((i & SocketEvent::HANGUP) ? POLLHUP : 0) | + ((i & SocketEvent::ERROR) ? POLLERR : 0); } NfsConnection::~NfsConnection() noexcept @@ -403,8 +403,8 @@ NfsConnection::DestroyContext() noexcept new leases */ defer_new_lease.Cancel(); - if (SocketMonitor::IsDefined()) - SocketMonitor::Steal(); + if (socket_event.IsDefined()) + socket_event.Steal(); callbacks.ForEach([](CancellableCallback &c){ c.PrepareDestroyContext(); @@ -434,25 +434,25 @@ NfsConnection::ScheduleSocket() noexcept const int which_events = nfs_which_events(context); - if (which_events == POLLOUT && SocketMonitor::IsDefined()) + if (which_events == POLLOUT && socket_event.IsDefined()) /* kludge: if libnfs asks only for POLLOUT, it means that it is currently waiting for the connect() to finish - rpc_reconnect_requeue() may have been called from inside nfs_service(); we must now unregister the old socket and register the new one instead */ - SocketMonitor::Steal(); + socket_event.Steal(); - if (!SocketMonitor::IsDefined()) { + if (!socket_event.IsDefined()) { SocketDescriptor _fd(nfs_get_fd(context)); if (!_fd.IsDefined()) return; _fd.EnableCloseOnExec(); - SocketMonitor::Open(_fd); + socket_event.Open(_fd); } - SocketMonitor::Schedule(libnfs_to_events(which_events)); + socket_event.Schedule(libnfs_to_events(which_events)); } inline int @@ -480,16 +480,14 @@ NfsConnection::Service(unsigned flags) noexcept return result; } -bool +void NfsConnection::OnSocketReady(unsigned flags) noexcept { assert(GetEventLoop().IsInside()); assert(deferred_close.empty()); - bool closed = false; - const bool was_mounted = mount_finished; - if (!mount_finished || (flags & SocketMonitor::HANGUP) != 0) + if (!mount_finished || (flags & SocketEvent::HANGUP) != 0) /* until the mount is finished, the NFS client may use various sockets, therefore we unregister and re-register it each time */ @@ -497,7 +495,7 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept which is a sure sign that libnfs will close the socket, which can lead to a race condition if epoll_ctl() is called later */ - SocketMonitor::Steal(); + socket_event.Steal(); const int result = Service(flags); @@ -509,7 +507,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept if (!was_mounted && mount_finished) { if (postponed_mount_error) { DestroyContext(); - closed = true; BroadcastMountError(std::move(postponed_mount_error)); } else if (result == 0) BroadcastMountSuccess(); @@ -521,7 +518,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept BroadcastError(std::make_exception_ptr(e)); DestroyContext(); - closed = true; } else if (nfs_get_fd(context) < 0) { /* this happens when rpc_reconnect_requeue() is called after the connection broke, but autoreconnect was @@ -535,7 +531,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept BroadcastError(std::make_exception_ptr(e)); DestroyContext(); - closed = true; } assert(context == nullptr || nfs_get_fd(context) >= 0); @@ -547,8 +542,6 @@ NfsConnection::OnSocketReady(unsigned flags) noexcept if (context != nullptr) ScheduleSocket(); - - return !closed; } inline void diff --git a/src/lib/nfs/Connection.hxx b/src/lib/nfs/Connection.hxx index 394163c9f..e76a7096b 100644 --- a/src/lib/nfs/Connection.hxx +++ b/src/lib/nfs/Connection.hxx @@ -21,7 +21,7 @@ #define MPD_NFS_CONNECTION_HXX #include "Cancellable.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "event/TimerEvent.hxx" #include "event/DeferEvent.hxx" #include "util/Compiler.h" @@ -40,7 +40,7 @@ class NfsLease; /** * An asynchronous connection to a NFS server. */ -class NfsConnection : SocketMonitor { +class NfsConnection { class CancellableCallback : public CancellablePointer { NfsConnection &connection; @@ -93,6 +93,7 @@ class NfsConnection : SocketMonitor { void Callback(int err, void *data) noexcept; }; + SocketEvent socket_event; DeferEvent defer_new_lease; TimerEvent mount_timeout_event; @@ -141,7 +142,7 @@ public: gcc_nonnull_all NfsConnection(EventLoop &_loop, const char *_server, const char *_export_name) noexcept - :SocketMonitor(_loop), + :socket_event(_loop, BIND_THIS_METHOD(OnSocketReady)), defer_new_lease(_loop, BIND_THIS_METHOD(RunDeferred)), mount_timeout_event(_loop, BIND_THIS_METHOD(OnMountTimeout)), server(_server), export_name(_export_name), @@ -152,6 +153,10 @@ public: */ ~NfsConnection() noexcept; + auto &GetEventLoop() const noexcept { + return socket_event.GetEventLoop(); + } + gcc_pure const char *GetServer() const noexcept { return server.c_str(); @@ -162,8 +167,6 @@ public: return export_name.c_str(); } - using SocketMonitor::GetEventLoop; - /** * Ensure that the connection is established. The connection * is kept up while at least one #NfsLease is registered. @@ -231,8 +234,7 @@ private: */ int Service(unsigned flags) noexcept; - /* virtual methods from SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override; + void OnSocketReady(unsigned flags) noexcept; /* callback for #mount_timeout_event */ void OnMountTimeout() noexcept; diff --git a/src/output/plugins/httpd/HttpdClient.cxx b/src/output/plugins/httpd/HttpdClient.cxx index fceb58f39..cfa92e3a7 100644 --- a/src/output/plugins/httpd/HttpdClient.cxx +++ b/src/output/plugins/httpd/HttpdClient.cxx @@ -216,7 +216,7 @@ HttpdClient::CancelQueue() noexcept ClearQueue(); if (current_page == nullptr) - CancelWrite(); + event.CancelWrite(); } ssize_t @@ -259,7 +259,7 @@ HttpdClient::TryWrite() noexcept /* another thread has removed the event source while this thread was waiting for httpd.mutex */ - CancelWrite(); + event.CancelWrite(); return true; } @@ -354,7 +354,7 @@ HttpdClient::TryWrite() noexcept if (pages.empty()) /* all pages are sent: remove the event source */ - CancelWrite(); + event.CancelWrite(); } } @@ -377,7 +377,7 @@ HttpdClient::PushPage(PagePtr page) noexcept queue_size += page->GetSize(); pages.emplace(std::move(page)); - ScheduleWrite(); + event.ScheduleWrite(); } void @@ -389,17 +389,14 @@ HttpdClient::PushMetaData(PagePtr page) noexcept metadata_sent = false; } -bool +void HttpdClient::OnSocketReady(unsigned flags) noexcept { - if (!BufferedSocket::OnSocketReady(flags)) - return false; - - if (flags & WRITE) + if (flags & SocketEvent::WRITE) if (!TryWrite()) - return false; + return; - return true; + BufferedSocket::OnSocketReady(flags); } BufferedSocket::InputResult diff --git a/src/output/plugins/httpd/HttpdClient.hxx b/src/output/plugins/httpd/HttpdClient.hxx index cfd7d80c5..b00e90706 100644 --- a/src/output/plugins/httpd/HttpdClient.hxx +++ b/src/output/plugins/httpd/HttpdClient.hxx @@ -196,8 +196,8 @@ private: void ClearQueue() noexcept; protected: - /* virtual methods from class SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override; + /* virtual methods from class BufferedSocket */ + void OnSocketReady(unsigned flags) noexcept override; InputResult OnSocketInput(void *data, size_t length) noexcept override; void OnSocketError(std::exception_ptr ep) noexcept override; diff --git a/src/zeroconf/AvahiPoll.cxx b/src/zeroconf/AvahiPoll.cxx index 2edec9da6..33c821af6 100644 --- a/src/zeroconf/AvahiPoll.cxx +++ b/src/zeroconf/AvahiPoll.cxx @@ -18,28 +18,29 @@ */ #include "AvahiPoll.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "event/TimerEvent.hxx" #include "time/Convert.hxx" static unsigned FromAvahiWatchEvent(AvahiWatchEvent e) { - return (e & AVAHI_WATCH_IN ? SocketMonitor::READ : 0) | - (e & AVAHI_WATCH_OUT ? SocketMonitor::WRITE : 0); + return (e & AVAHI_WATCH_IN ? SocketEvent::READ : 0) | + (e & AVAHI_WATCH_OUT ? SocketEvent::WRITE : 0); } static AvahiWatchEvent ToAvahiWatchEvent(unsigned e) { - return AvahiWatchEvent((e & SocketMonitor::READ ? AVAHI_WATCH_IN : 0) | - (e & SocketMonitor::WRITE ? AVAHI_WATCH_OUT : 0) | - (e & SocketMonitor::ERROR ? AVAHI_WATCH_ERR : 0) | - (e & SocketMonitor::HANGUP ? AVAHI_WATCH_HUP : 0)); + return AvahiWatchEvent((e & SocketEvent::READ ? AVAHI_WATCH_IN : 0) | + (e & SocketEvent::WRITE ? AVAHI_WATCH_OUT : 0) | + (e & SocketEvent::ERROR ? AVAHI_WATCH_ERR : 0) | + (e & SocketEvent::HANGUP ? AVAHI_WATCH_HUP : 0)); } -struct AvahiWatch final : private SocketMonitor { -private: +struct AvahiWatch final { + SocketEvent event; + const AvahiWatchCallback callback; void *const userdata; @@ -49,14 +50,14 @@ public: AvahiWatch(SocketDescriptor _fd, AvahiWatchEvent _event, AvahiWatchCallback _callback, void *_userdata, EventLoop &_loop) - :SocketMonitor(_fd, _loop), + :event(_loop, BIND_THIS_METHOD(OnSocketReady), _fd), callback(_callback), userdata(_userdata), received(AvahiWatchEvent(0)) { - Schedule(FromAvahiWatchEvent(_event)); + event.Schedule(FromAvahiWatchEvent(_event)); } static void WatchUpdate(AvahiWatch *w, AvahiWatchEvent event) { - w->Schedule(FromAvahiWatchEvent(event)); + w->event.Schedule(FromAvahiWatchEvent(event)); } static AvahiWatchEvent WatchGetEvents(AvahiWatch *w) { @@ -68,12 +69,10 @@ public: } private: - /* virtual methods from class SocketMonitor */ - bool OnSocketReady(unsigned flags) noexcept override { + void OnSocketReady(unsigned flags) noexcept { received = ToAvahiWatchEvent(flags); - callback(this, GetSocket().Get(), received, userdata); + callback(this, event.GetSocket().Get(), received, userdata); received = AvahiWatchEvent(0); - return true; } }; diff --git a/src/zeroconf/ZeroconfBonjour.cxx b/src/zeroconf/ZeroconfBonjour.cxx index 44fcb6d90..247c2cd36 100644 --- a/src/zeroconf/ZeroconfBonjour.cxx +++ b/src/zeroconf/ZeroconfBonjour.cxx @@ -20,7 +20,7 @@ #include "ZeroconfBonjour.hxx" #include "ZeroconfInternal.hxx" #include "Listen.hxx" -#include "event/SocketMonitor.hxx" +#include "event/SocketEvent.hxx" #include "util/Domain.hxx" #include "Log.hxx" #include "util/Compiler.h" @@ -31,15 +31,19 @@ static constexpr Domain bonjour_domain("bonjour"); -class BonjourMonitor final : public SocketMonitor { +class BonjourMonitor final { DNSServiceRef service_ref; + SocketEvent socket_event; + public: BonjourMonitor(EventLoop &_loop, DNSServiceRef _service_ref) - :SocketMonitor(SocketDescriptor(DNSServiceRefSockFD(_service_ref)), - _loop), - service_ref(_service_ref) { - ScheduleRead(); + :service_ref(_service_ref), + socket_event(SocketDescriptor(DNSServiceRefSockFD(service_ref)), + BIND_THIS_METHOD(OnSocketReady), + _loop) + { + socket_event.ScheduleRead(); } ~BonjourMonitor() { @@ -48,9 +52,8 @@ public: protected: /* virtual methods from class SocketMonitor */ - bool OnSocketReady([[maybe_unused]] unsigned flags) noexcept override { + void OnSocketReady([[maybe_unused]] unsigned flags) noexcept override { DNSServiceProcessResult(service_ref); - return true; } };