diff options
Diffstat (limited to 'src/event/MultiSocketMonitor.hxx')
-rw-r--r-- | src/event/MultiSocketMonitor.hxx | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/src/event/MultiSocketMonitor.hxx b/src/event/MultiSocketMonitor.hxx index 8ee81a508..680930037 100644 --- a/src/event/MultiSocketMonitor.hxx +++ b/src/event/MultiSocketMonitor.hxx @@ -23,22 +23,25 @@ #include "check.h" #include "Compiler.h" -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP #include "IdleMonitor.hxx" #include "TimeoutMonitor.hxx" #include "SocketMonitor.hxx" -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP #include <glib.h> #endif #include <forward_list> +#include <iterator> #include <assert.h> #include <stdint.h> #ifdef WIN32 -/* ERRORis a WIN32 macro that poisons our namespace; this is a - kludge to allow us to use it anyway */ +/* ERROR is a WIN32 macro that poisons our namespace; this is a kludge + to allow us to use it anyway */ #ifdef ERROR #undef ERROR #endif @@ -47,14 +50,17 @@ class EventLoop; /** - * Monitor multiple sockets. + * Similar to #SocketMonitor, 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 -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP : private IdleMonitor, private TimeoutMonitor #endif { -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP class SingleFD final : public SocketMonitor { MultiSocketMonitor &multi; @@ -99,7 +105,9 @@ class MultiSocketMonitor friend class SingleFD; bool ready, refresh; -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP struct Source { GSource base; @@ -138,12 +146,14 @@ class MultiSocketMonitor std::forward_list<SingleFD> fds; public: -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP static constexpr unsigned READ = SocketMonitor::READ; static constexpr unsigned WRITE = SocketMonitor::WRITE; static constexpr unsigned ERROR = SocketMonitor::ERROR; static constexpr unsigned HANGUP = SocketMonitor::HANGUP; -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP static constexpr unsigned READ = G_IO_IN; static constexpr unsigned WRITE = G_IO_OUT; static constexpr unsigned ERROR = G_IO_ERR; @@ -153,16 +163,18 @@ public: MultiSocketMonitor(EventLoop &_loop); ~MultiSocketMonitor(); -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP using IdleMonitor::GetEventLoop; -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP EventLoop &GetEventLoop() { return loop; } #endif public: -#ifndef USE_EPOLL +#ifdef USE_GLIB_EVENTLOOP gcc_pure uint64_t GetTime() const { return g_source_get_time(&source->base); @@ -170,10 +182,12 @@ public: #endif void InvalidateSockets() { -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP refresh = true; IdleMonitor::Schedule(); -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP /* no-op because GLib always calls the GSource's "prepare" method before each poll() anyway */ #endif @@ -181,7 +195,7 @@ public: void AddSocket(int fd, unsigned events) { fds.emplace_front(*this, fd, events); -#ifndef USE_EPOLL +#ifdef USE_GLIB_EVENTLOOP g_source_add_poll(&source->base, &fds.front().pfd); #endif } @@ -198,9 +212,11 @@ public: i->SetEvents(events); prev = i; } else { -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP i->Steal(); -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP g_source_remove_poll(&source->base, &i->pfd); #endif fds.erase_after(prev); @@ -215,7 +231,7 @@ protected: virtual int PrepareSockets() = 0; virtual void DispatchSockets() = 0; -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP private: void SetReady() { ready = true; @@ -231,7 +247,9 @@ private: virtual void OnIdle() final; -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP public: /* GSource callbacks */ static gboolean Prepare(GSource *source, gint *timeout_r); |