11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
29PROMEKI_NAMESPACE_BEGIN
42class EventLoopPollCache;
89 enum ProcessEventsFlag : uint32_t {
111 using Label = StringRegistry<
"EventLoopLabel">::Item;
117 static EventLoop *current();
137 EventLoop(
const EventLoop &) =
delete;
138 EventLoop &operator=(
const EventLoop &) =
delete;
155 void processEvents(uint32_t flags = 0,
unsigned int timeoutMs = 0);
165 void quit(
int returnCode = 0);
175 void postCallable(Function<
void()> func);
206 void postCallable(Label label, Function<
void()> func);
236 void postCallable(ObjectBase *owner, Label label, Function<
void()> func);
248 void postEvent(ObjectBase *receiver, Event *event);
264 int startTimer(ObjectBase *receiver,
unsigned int intervalMs,
bool singleShot =
false);
278 int startTimer(
unsigned int intervalMs, Function<
void()> func,
bool singleShot =
false);
294 void stopTimer(
int timerId);
300 bool isRunning()
const {
return _running.value(); }
306 int exitCode()
const {
return _exitCode.value(); }
320 unsigned int nextTimerTimeout()
const;
332 static constexpr uint32_t IoRead = 0x01;
333 static constexpr uint32_t IoWrite = 0x02;
334 static constexpr uint32_t IoError = 0x04;
347 using IoCallback = Function<void(
int fd, uint32_t events)>;
392 int addIoSource(
int fd, uint32_t events, IoCallback cb);
405 void removeIoSource(
int handle);
464 Duration wallElapsed;
473 int64_t timersCount = 0;
474 int64_t eventsCount = 0;
475 int64_t callablesCount = 0;
479 HashMap<int, EventStat> eventsByType;
490 HashMap<uint64_t, EventStat> callablesByLabel;
504 using ReportFunction = Function<void(
const Report &)>;
524 void setName(
const String &name);
562 void installMonitor(
const Duration &interval, ReportFunction fn = {});
583 void removeMonitor();
593 bool hasMonitor()
const;
607 Report peekStats()
const;
619 Report consumeStats();
622 struct CallableItem {
623 Function<void()> func;
631 uint64_t labelId = Label::InvalidID;
634 ObjectBase *receiver;
640 using Item = std::variant<CallableItem, EventItem, QuitItem>;
644 ObjectBase *receiver;
645 Function<void()> func;
646 unsigned int intervalMs;
651 static thread_local EventLoop *_current;
654 Atomic<bool> _running;
655 Atomic<int> _exitCode;
665 mutable Mutex _timersMutex;
666 List<TimerInfo> _timers;
667 Atomic<int> _nextTimerId{1};
675 using WakeFdUPtr = UniquePtr<EventLoopWakeFd>;
689 bool pendingRemove =
false;
691 mutable Mutex _ioMutex;
692 List<IoSource> _ioSources;
693 Atomic<int> _nextIoHandle{1};
701 using PollCacheUPtr = UniquePtr<EventLoopPollCache>;
702 PollCacheUPtr _pollCache;
715 bool dispatchItem(Item &item);
716 void processTimers();
727 void waitOnSources(
unsigned int waitMs);
745 Atomic<bool> _monitorActive;
746 mutable Mutex _statsMutex;
747 TimeStamp _statsLastSnapshot;
749 int64_t _sleepNs = 0;
750 int64_t _queueWaitNs = 0;
751 int64_t _timersNs = 0;
752 int64_t _eventsNs = 0;
753 int64_t _callablesNs = 0;
756 int64_t _timersCount = 0;
757 int64_t _eventsCount = 0;
758 int64_t _callablesCount = 0;
759 int64_t _ioCount = 0;
761 HashMap<int, EventStatNs> _eventsByType;
766 HashMap<uint64_t, EventStatNs> _callablesByLabel;
768 int _monitorTimerId = 0;
769 ReportFunction _monitorFn;
784 StatsBracket(EventLoop *loop, int64_t *durBucket,
785 int64_t *countBucket);
787 void attributeEventType(
int type) { _eventType = type; }
788 void attributeCallableLabel(uint64_t labelId) {
789 _callableLabel = labelId;
795 int64_t *_countBucket;
798 uint64_t _callableLabel = Label::InvalidID;
799 bool _active =
false;
802 friend class StatsBracket;
807 static void defaultMonitorReporter(
const Report &r);