11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
29PROMEKI_NAMESPACE_BEGIN
83 enum ProcessEventsFlag : uint32_t {
105 using Label = StringRegistry<
"EventLoopLabel">::Item;
111 static EventLoop *current();
131 EventLoop(
const EventLoop &) =
delete;
132 EventLoop &operator=(
const EventLoop &) =
delete;
149 void processEvents(uint32_t flags = 0,
unsigned int timeoutMs = 0);
159 void quit(
int returnCode = 0);
169 void postCallable(Function<
void()> func);
200 void postCallable(Label label, Function<
void()> func);
212 void postEvent(ObjectBase *receiver, Event *event);
228 int startTimer(ObjectBase *receiver,
unsigned int intervalMs,
bool singleShot =
false);
242 int startTimer(
unsigned int intervalMs, Function<
void()> func,
bool singleShot =
false);
258 void stopTimer(
int timerId);
264 bool isRunning()
const {
return _running.value(); }
270 int exitCode()
const {
return _exitCode.value(); }
284 unsigned int nextTimerTimeout()
const;
296 static constexpr uint32_t IoRead = 0x01;
297 static constexpr uint32_t IoWrite = 0x02;
298 static constexpr uint32_t IoError = 0x04;
311 using IoCallback = Function<void(
int fd, uint32_t events)>;
356 int addIoSource(
int fd, uint32_t events, IoCallback cb);
369 void removeIoSource(
int handle);
428 Duration wallElapsed;
437 int64_t timersCount = 0;
438 int64_t eventsCount = 0;
439 int64_t callablesCount = 0;
443 HashMap<int, EventStat> eventsByType;
454 HashMap<uint64_t, EventStat> callablesByLabel;
468 using ReportFunction = Function<void(
const Report &)>;
488 void setName(
const String &name);
526 void installMonitor(
const Duration &interval, ReportFunction fn = {});
547 void removeMonitor();
557 bool hasMonitor()
const;
571 Report peekStats()
const;
583 Report consumeStats();
586 struct CallableItem {
587 Function<void()> func;
595 uint64_t labelId = Label::InvalidID;
598 ObjectBase *receiver;
604 using Item = std::variant<CallableItem, EventItem, QuitItem>;
608 ObjectBase *receiver;
609 Function<void()> func;
610 unsigned int intervalMs;
615 static thread_local EventLoop *_current;
618 Atomic<bool> _running;
619 Atomic<int> _exitCode;
629 mutable Mutex _timersMutex;
630 List<TimerInfo> _timers;
631 Atomic<int> _nextTimerId{1};
639 using WakeFdUPtr = UniquePtr<EventLoopWakeFd>;
653 bool pendingRemove =
false;
655 mutable Mutex _ioMutex;
656 List<IoSource> _ioSources;
657 Atomic<int> _nextIoHandle{1};
670 bool dispatchItem(Item &item);
671 void processTimers();
682 void waitOnSources(
unsigned int waitMs);
700 Atomic<bool> _monitorActive;
701 mutable Mutex _statsMutex;
702 TimeStamp _statsLastSnapshot;
704 int64_t _sleepNs = 0;
705 int64_t _queueWaitNs = 0;
706 int64_t _timersNs = 0;
707 int64_t _eventsNs = 0;
708 int64_t _callablesNs = 0;
711 int64_t _timersCount = 0;
712 int64_t _eventsCount = 0;
713 int64_t _callablesCount = 0;
714 int64_t _ioCount = 0;
716 HashMap<int, EventStatNs> _eventsByType;
721 HashMap<uint64_t, EventStatNs> _callablesByLabel;
723 int _monitorTimerId = 0;
724 ReportFunction _monitorFn;
739 StatsBracket(EventLoop *loop, int64_t *durBucket,
740 int64_t *countBucket);
742 void attributeEventType(
int type) { _eventType = type; }
743 void attributeCallableLabel(uint64_t labelId) {
744 _callableLabel = labelId;
750 int64_t *_countBucket;
753 uint64_t _callableLabel = Label::InvalidID;
754 bool _active =
false;
757 friend class StatsBracket;
762 static void defaultMonitorReporter(
const Report &r);