aboutsummaryrefslogtreecommitdiffstats
path: root/src/event/MultiSocketMonitor.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/event/MultiSocketMonitor.hxx')
-rw-r--r--src/event/MultiSocketMonitor.hxx58
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);