25#ifndef JOIN_CORE_REACTOR_HPP
26#define JOIN_CORE_REACTOR_HPP
36#include <unordered_map>
37#include <unordered_set>
95 virtual void onEvent (
int fd, uint32_t revents)
109 else if (revents & EPOLLOUT)
137 virtual void onClose ([[maybe_unused]]
int fd)
146 virtual void onError ([[maybe_unused]]
int fd)
162 static constexpr size_t _deletedReserve = 64;
165 static constexpr size_t _queueSize = 1024;
168 static constexpr size_t _maxEvents = 1024;
180 explicit WheelPolicy (
Reactor& reactor) noexcept
191 template <
class Wheel>
192 int start ([[maybe_unused]]
Wheel&
wheel, [[maybe_unused]] std::chrono::nanoseconds period)
noexcept
201 void stop ()
noexcept
210 bool isRunnerThread ()
const noexcept
220 template <
class Wheel>
221 int flush ([[maybe_unused]]
Wheel&
wheel)
noexcept
228 return _reactor.wakeup ();
237 template <
class Wheel>
238 static uint64_t advance (
Wheel&
wheel)
noexcept
240 return wheel.advance ();
249 template <
class Wheel>
250 static timespec* timeout (
const Wheel&
wheel, timespec& ts)
noexcept
252 const std::chrono::nanoseconds next =
wheel.next ();
254 if (next == std::chrono::nanoseconds::max ())
324 bool sync = true) noexcept;
332 int delHandler (
int fd,
bool sync = true) noexcept;
351 void stop (
bool sync = true) noexcept;
364 int mbind (
int numa)
const noexcept;
371 int mlock () const noexcept;
398 enum class CommandType
409 struct alignas (64) Command
414 EventHandler* handler;
415 std::atomic<bool>* done;
416 std::error_code* errc;
427 int registerHandler (
int fd, EventHandler* handler, uint32_t events)
noexcept;
434 int unregisterHandler (
int fd)
noexcept;
448 int writeCommand (
const Command& cmd)
noexcept;
454 int wakeup () noexcept;
460 void processCommand (const Command& cmd) noexcept;
465 void readCommands () noexcept;
471 void dispatchEvent (const epoll_event& event);
483 bool isActive (
int fd) const noexcept;
495 alignas (64) std::atomic<bool> _notified{
false};
501 std::unordered_map<int, EventHandler*> _handlers;
504 std::unordered_set<int> _deleted;
507 std::atomic<bool> _running{
false};
555 static pthread_t
handle ();
563 static int mbind (
int numa);
timing wheel.
Definition wheel.hpp:58
Event handler interface class.
Definition reactor.hpp:51
EventHandler(const EventHandler &other)=default
copy constructor.
virtual void onClose(int fd)
method called when handle was closed by the peer.
Definition reactor.hpp:137
virtual ~EventHandler()=default
destroy instance.
virtual void onError(int fd)
method called when an error occurred on handle.
Definition reactor.hpp:146
EventHandler()=default
create instance.
virtual void onReadable(int fd)
method called when data are ready to be read on handle.
Definition reactor.hpp:119
virtual void onEvent(int fd, uint32_t revents)
method called when events are reported on handle.
Definition reactor.hpp:95
EventHandler & operator=(const EventHandler &other)=default
copy assignment operator.
EventHandler(EventHandler &&other)=default
move constructor.
virtual void onWriteable(int fd)
method called when data are ready to be written on handle.
Definition reactor.hpp:128
fixed-capacity move-only allocation-free alternative to std::function.
Definition function.hpp:44
monotonic clock policy (stable, adjusted, recommended default).
Definition clock.hpp:105
Convenience class that owns a Reactor running on a dedicated background thread.
Definition reactor.hpp:517
static int affinity()
get reactor thread affinity.
Definition reactor.cpp:630
static int priority()
get reactor thread priority.
Definition reactor.cpp:648
static pthread_t handle()
get the handle of the reactor thread.
Definition reactor.cpp:657
static Reactor & reactor()
get the global Reactor instance.
Definition reactor.cpp:612
static int mlock()
lock command queue and timer wheel memory in RAM.
Definition reactor.cpp:677
Reactor class.
Definition reactor.hpp:159
bool isRunning() const noexcept
check if the event loop is running.
Definition reactor.cpp:328
Reactor(Reactor &&other)=delete
move constructor.
Reactor()
default constructor.
Definition reactor.cpp:47
Function< void(), 64 > InvokeHandler
function invoked on the reactor thread.
Definition reactor.hpp:273
void waitStopped() const noexcept
wait for the event loop thread to terminate.
Definition reactor.cpp:284
bool isReactorThread() const noexcept
check if the calling thread is the reactor thread.
Definition reactor.cpp:337
int mlock() const noexcept
lock command queue and timer wheel memory in RAM.
Definition reactor.cpp:314
int delHandler(int fd, bool sync=true) noexcept
delete handler from reactor.
Definition reactor.cpp:156
Reactor & operator=(const Reactor &other)=delete
copy assignment operator.
void run()
run the event loop (blocking).
Definition reactor.cpp:242
Reactor(const Reactor &other)=delete
copy constructor.
~Reactor() noexcept
destroy instance.
Definition reactor.cpp:89
Wheel & wheel() noexcept
get the timer wheel advanced by the event loop.
Definition reactor.hpp:389
void stop(bool sync=true) noexcept
stop the event loop, ignored if no event loop is running.
Definition reactor.cpp:259
int addHandler(int fd, EventHandler *handler, bool wantRead=true, bool wantWrite=false, bool sync=true) noexcept
add handler to reactor.
Definition reactor.cpp:101
int invoke(InvokeHandler *fn, bool sync=true) noexcept
invoke a function from the reactor thread.
Definition reactor.cpp:199
thread class.
Definition thread.hpp:180
static constexpr pid_t invalidId
invalid thread id.
Definition thread.hpp:183
Monotonic::Wheel< 64 > Wheel
Definition monotonic_wheel_test.cpp:41
Definition acceptor.hpp:32
struct timespec toTimespec(std::chrono::time_point< Clock, Duration > timePoint)
converts time_point to timespec.
Definition utils.hpp:431
BasicQueue< Type, Backend, SyncPolicy< Type, Backend > > Queue
queue type alias combining backend and policy.
Definition queue.hpp:1040
#define JOIN_LIKELY(x)
Definition utils.hpp:50
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51