diff options
Diffstat (limited to 'src/event/Loop.hxx')
-rw-r--r-- | src/event/Loop.hxx | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/src/event/Loop.hxx b/src/event/Loop.hxx index 62e733747..029d01245 100644 --- a/src/event/Loop.hxx +++ b/src/event/Loop.hxx @@ -24,8 +24,8 @@ #include "thread/Id.hxx" #include "Compiler.h" -#ifdef USE_EPOLL -#include "system/EPollFD.hxx" +#ifdef USE_INTERNAL_EVENTLOOP +#include "PollGroup.hxx" #include "thread/Mutex.hxx" #include "WakeFD.hxx" #include "SocketMonitor.hxx" @@ -33,11 +33,13 @@ #include <functional> #include <list> #include <set> -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP #include <glib.h> #endif -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP class TimeoutMonitor; class IdleMonitor; class SocketMonitor; @@ -45,12 +47,21 @@ class SocketMonitor; #include <assert.h> +/** + * An event loop that polls for events on file/socket descriptors. + * + * This class is not thread-safe, all methods must be called from the + * thread that runs it, except where explicitly documented as + * thread-safe. + * + * @see SocketMonitor, MultiSocketMonitor, TimeoutMonitor, IdleMonitor + */ class EventLoop final -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP : private SocketMonitor #endif { -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP struct TimerRecord { /** * Projected monotonic_clock_ms() value when this @@ -73,8 +84,6 @@ class EventLoop final } }; - EPollFD epoll; - WakeFD wake_fd; std::multiset<TimerRecord> timers; @@ -87,10 +96,11 @@ class EventLoop final bool quit; - static constexpr unsigned MAX_EVENTS = 16; - unsigned n_events; - epoll_event events[MAX_EVENTS]; -#else + PollGroup poll_group; + PollResult poll_result; +#endif + +#ifdef USE_GLIB_EVENTLOOP GMainContext *context; GMainLoop *loop; #endif @@ -101,24 +111,32 @@ class EventLoop final ThreadId thread; public: -#ifdef USE_EPOLL +#ifdef USE_INTERNAL_EVENTLOOP struct Default {}; EventLoop(Default dummy=Default()); ~EventLoop(); + /** + * A caching wrapper for MonotonicClockMS(). + */ unsigned GetTimeMS() const { return now_ms; } + /** + * Stop execution of this #EventLoop at the next chance. This + * method is thread-safe and non-blocking: after returning, it + * is not guaranteed that the EventLoop has really stopped. + */ void Break(); bool AddFD(int _fd, unsigned flags, SocketMonitor &m) { - return epoll.Add(_fd, flags, &m); + return poll_group.Add(_fd, flags, &m); } bool ModifyFD(int _fd, unsigned flags, SocketMonitor &m) { - return epoll.Modify(_fd, flags, &m); + return poll_group.Modify(_fd, flags, &m); } /** @@ -126,7 +144,7 @@ public: * has been closed. This is like RemoveFD(), but does not * attempt to use #EPOLL_CTL_DEL. */ - void Abandon(SocketMonitor &m); + bool Abandon(int fd, SocketMonitor &m); bool RemoveFD(int fd, SocketMonitor &m); @@ -138,13 +156,19 @@ public: void AddCall(std::function<void()> &&f); + /** + * The main function of this class. It will loop until + * Break() gets called. Can be called only once. + */ void Run(); private: virtual bool OnSocketReady(unsigned flags) override; public: -#else +#endif + +#ifdef USE_GLIB_EVENTLOOP EventLoop() :context(g_main_context_new()), loop(g_main_loop_new(context, false)), |