qb  2.0.0.0
C++17 Actor Framework
qb Issue Watch Star Fork Follow @isndev
Loading...
Searching...
No Matches
listener.h
Go to the documentation of this file.
1
24
25#ifndef QB_IO_ASYNC_LISTENER_H_
26#define QB_IO_ASYNC_LISTENER_H_
27
28#include <algorithm>
32#include <thread>
33#include <vector>
34#include "event/base.h"
35
36namespace qb::io::async {
37
50class listener {
51public:
61 thread_local static listener current;
62
75 template <typename _Event, typename _Actor>
76 class RegisteredKernelEvent final : public IRegisteredKernelEvent {
77 friend class listener;
78
79 _Actor &_actor;
80 _Event _event;
81
85 ~RegisteredKernelEvent() final {
86 _event.stop();
87 }
88
94 explicit RegisteredKernelEvent(ev::loop_ref loop, _Actor &actor) noexcept
95 : _actor(actor)
96 , _event(loop) {}
97
105 void
106 invoke() final {
107 if constexpr (has_member_func_is_alive<_Actor>::value) {
108 if (likely(_actor.is_alive()))
109 _actor.on(_event);
110 } else
111 _actor.on(_event);
112 }
113 };
114
115private:
116 ev::dynamic_loop _loop;
118 _registeredEvents;
119 std::size_t _nb_invoked_events = 0;
120
121public:
129 : _loop(EVFLAG_AUTO) {}
130
139 void
141 if (!_registeredEvents.empty()) {
142 for (auto it : _registeredEvents)
143 delete it;
144 _registeredEvents.clear();
145 run(EVRUN_ONCE);
146 }
147 }
148
154 ~listener() noexcept {
155 clear();
156 }
157
170 template <typename EV_EVENT>
171 void
172 on(EV_EVENT &event, int revents) {
173 auto &w = *reinterpret_cast<event::base<EV_EVENT> *>(&event);
174 w._revents = revents;
175 w._interface->invoke();
176 ++_nb_invoked_events;
177 }
178
195 template <typename _Event, typename _Actor, typename... _Args>
196 _Event &
197 registerEvent(_Actor &actor, _Args &&...args) {
198 auto revent = new RegisteredKernelEvent<_Event, _Actor>(_loop, actor);
199 revent->_event.template set<listener, &listener::on<typename _Event::ev_t>>(
200 this);
201 revent->_event._interface = revent;
202
203 if constexpr (sizeof...(_Args) > 0)
204 revent->_event.set(std::forward<_Args>(args)...);
205
206 _registeredEvents.emplace(revent);
207 return revent->_event;
208 }
209
221 void
223 _registeredEvents.erase(kevent);
224 delete kevent;
225 }
226
233 [[nodiscard]] inline ev::loop_ref
234 loop() const {
235 return _loop;
236 }
237
249 inline void
250 run(int flag = 0) {
251 _nb_invoked_events = 0;
252 _loop.run(flag);
253 }
254
261 inline void
263 _loop.break_loop();
264 }
265
271 [[nodiscard]] inline std::size_t
273 return _nb_invoked_events;
274 }
275
280 [[nodiscard]] inline std::size_t
281 size() const {
282 return _registeredEvents.size();
283 }
284};
285
293inline void
295 // listener::current.clear();
296}
297
308inline std::size_t
309run(int flag = 0) {
310 listener::current.run(flag);
311 return listener::current.nb_invoked_event();
312}
313
321inline std::size_t
323 listener::current.run(EVRUN_ONCE);
324 return listener::current.nb_invoked_event();
325}
326
335inline std::size_t
336run_until(bool const &status) {
337 std::size_t nb_invoked_events = 0;
338 while (status) {
339 listener::current.run(EVRUN_NOWAIT);
340 nb_invoked_events += listener::current.nb_invoked_event();
341 }
342 return nb_invoked_events;
343}
344
350inline void
352 listener::current.break_one();
353}
354
355} // namespace qb::io::async
356
357#endif // QB_IO_ASYNC_LISTENER_H_
Base class for asynchronous events in the QB IO library.
Branch prediction hint utilities for performance optimization.
Interface for kernel event registration and invocation.
Definition base.h:42
virtual void invoke()=0
Event invocation method, called by the listener when the event triggers.
Template wrapper for concrete event handlers and their associated libev watchers.
Definition listener.h:76
ev::loop_ref loop() const
Get a reference to the underlying libev event loop.
Definition listener.h:234
std::size_t size() const
Get the number of currently registered event handlers.
Definition listener.h:281
listener()
Constructor.
Definition listener.h:128
static thread_local listener current
Thread-local instance of the listener.
Definition listener.h:61
void break_one()
Request the event loop to break out of its current run() cycle.
Definition listener.h:262
std::size_t nb_invoked_event() const
Get the number of events invoked during the last call to run().
Definition listener.h:272
void run(int flag=0)
Run the event loop to process pending events.
Definition listener.h:250
void unregisterEvent(IRegisteredKernelEvent *kevent)
Unregister an event handler and its associated libev watcher.
Definition listener.h:222
void clear()
Clear all registered events from this listener.
Definition listener.h:140
_Event & registerEvent(_Actor &actor, _Args &&...args)
Register an event handler (actor/object) for a specific asynchronous event type.
Definition listener.h:197
~listener() noexcept
Destructor.
Definition listener.h:154
void on(EV_EVENT &event, int revents)
Generic event callback handler invoked by libev for any active watcher.
Definition listener.h:172
Actor actor
Alias for the Actor class.
Definition Actor.h:1046
std::size_t run_until(bool const &status)
Run the event loop for the current thread until a condition is met.
Definition listener.h:336
void init()
Initialize the asynchronous event system for the current thread.
Definition listener.h:294
std::size_t run(int flag=0)
Run the event loop for the current thread.
Definition listener.h:309
void break_parent()
Request the parent (current thread's) event loop to break.
Definition listener.h:351
std::size_t run_once()
Run the event loop once for the current thread, waiting for at least one event.
Definition listener.h:322
std::unordered_set< K, H, E, A > unordered_set
The primary unordered set implementation.
Definition unordered_set.h:81
bool likely(bool expr)
Hint for branch prediction when a condition is expected to be true.
Definition branch_hints.h:49
Advanced type traits and metaprogramming utilities for the QB Framework.
Optimized unordered set implementations.