20 IN = ASE_SYSVAL_POLLINIT[0],
21 PRI = ASE_SYSVAL_POLLINIT[1],
22 OUT = ASE_SYSVAL_POLLINIT[2],
28 ERR = ASE_SYSVAL_POLLINIT[7],
29 HUP = ASE_SYSVAL_POLLINIT[8],
30 NVAL = ASE_SYSVAL_POLLINIT[9],
54class DispatcherSource;
63#if defined __G_LIB_H__ || defined DOXYGEN
64typedef ::GMainContext GlibGMainContext;
66struct GlibGMainContext;
70template<
typename Func>
83 virtual void destroy_loop () = 0;
92 template<
typename Result>
struct Promise;
98 virtual void cancel (LoopID *idp) = 0;
108 template<IsLoopCallback Func>
110 template<IsLoopCallback Func>
115 template<
class BoolVo
idPollFunctor>
121 virtual void quit (
int quit_code = 0) = 0;
128 template<
typename Result>
136 enum Phase { NONE, COLLECT, PREPARE, CHECK, DISPATCH, DESTROY };
158 uint may_recurse_ : 1;
159 uint dispatching_ : 1;
160 uint was_dispatching_ : 1;
164 LoopID source_id () {
return loop_ ? id_ : LoopID::INVALID; }
168 int64 *timeout_usecs_p) = 0;
171 virtual void destroy ();
176 void primary (
bool is_primary);
194 virtual void destroy ();
198 {
return make_shared (slot); }
206 int8 signum_ = 0, index_ = 0, shift_ = 0;
213 virtual void destroy ();
218 {
return make_shared (signum, slot); }
219 static void install_sigaction (
int8);
235 virtual void destroy ();
239 {
return make_shared (pid, slot); }
248 uint interval_msecs_;
249 bool first_interval_;
265 {
return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
267 {
return make_shared (slot, initial_interval_msecs, repeat_interval_msecs); }
276 void construct (
const String &mode);
281 virtual void destroy ();
283 uint never_close_ : 1;
285 const uint oneshot_ : 1;
295 {
return make_shared (slot, fd, mode); }
297 {
return make_shared (slot, fd, mode); }
302Loop::exec_dispatcher (
const DispatcherSlot &slot,
LoopPriority priority)
304 return add_source (DispatcherSource::create (slot), priority);
310 return add_source (USignalSource::create (signum, slot), priority);
313template<
class BoolVo
idPollFunctor> LoopID
318 return add_source (PollFDSource::create (slot, fd, mode), priority);
321template<IsLoopCallback Func> LoopID
324 using ReturnType =
decltype (func());
326 const uint interval_ms = interval.
count();
327 return add_source (TimedSource::create (std::move (slot), interval_ms, interval_ms), priority);
330template<IsLoopCallback Func> LoopID
336template<
class Coroutine>
requires IsAwaitable<std::invoke_result_t<Coroutine>> LoopID
345 auto start_coroutine = [coroutine_ptr] ()
348 static auto loop_coawait = [] (
auto coroutine_ptr) -> DetachedTask
351 co_await (*coroutine_ptr) ();
355 loop_coawait (coroutine_ptr);
363template<
typename Result>
373 await_ready()
const noexcept
376 return promise_->state_.index() > 0;
382 if (promise_->state_.index() > 0)
384 promise_->waiters_.push_back (waiter);
403 operator co_await()
noexcept
435 explicit Promise (
Loop &loop) : loop_ (&loop) {}
438 resolve_impl (StateVariant &&new_state)
443 if (state_.index() != 0)
return;
444 state_ = std::move (new_state);
445 waiters_to_notify.swap (waiters_);
448 for (
auto h : waiters_to_notify)
450 loop_->add ([h, keep_alive]
459template<
typename Result>
462template<
typename T>
auto
463operator co_await (LoopPromiseP<T> p)
465 return p->operator
co_await();
472 struct EnableMakeShared :
Promise<Result> {
476 auto resolver = [promisep] (Result value) { promisep->resolve (value); };
489 struct EnableMakeShared :
Promise<void> {
493 auto resolver = [promisep] () { promisep->resolve(); };
Loop source for handler execution.
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Loop implementation with internal state.
Loop source for callback execution.
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)=0
Prepare the source for dispatching (true return) or polling (false).
bool recursion() const
Indicates wether the source is currently in recursion.
virtual bool check(const LoopState &state)=0
Check the source and its PollFD descriptors for dispatching (true return).
void add_poll(PollFD *const pfd)
Add a PollFD descriptors for poll(2) and check().
bool primary() const
Indicate whether this source is primary.
Loop * loop() const
Get the main loop for this source.
virtual bool dispatch(const LoopState &state)=0
Dispatch source, returns if it should be kept alive.
bool may_recurse() const
Indicates if this source may recurse.
void loop_remove()
Remove this source from its event loop if any.
void remove_poll(PollFD *const pfd)
Remove a previously added PollFD.
Loop object, polling for events and executing callbacks in accordance.
std::shared_ptr< Promise< uint64_t > > delay(std::chrono::milliseconds ms)
Create a promise that resolves after ms milliseconds and returns the elapsed delay.
virtual void cancel(LoopID id)=0
Cancel a source and remove it from the loop.
virtual bool set_g_main_context(GlibGMainContext *glib_main_context)=0
Set context to integrate with a GLib GMainContext loop.
virtual void quit(int quit_code=0)=0
Cause run() to return with quit_code.
LoopID exec_io_handler(BoolVoidPollFunctor &&bvf, int fd, const String &mode, LoopPriority priority=LoopPriority::NORMAL)
Execute a callback after polling for mode on fd, returning true repeats callback.
virtual void iterate_pending()=0
Call iterate() until no immediate dispatching is needed.
LoopID exec_usignal(int8 signum, const USignalSlot &sl, LoopPriority priority=LoopPriority::USIGNAL)
Execute a single dispatcher callback for prepare, check, dispatch.
virtual int run()=0
Run loop iterations until a call to quit() or finishable becomes true.
virtual LoopID exec_sigchld(int64_t pid, const SigchldSlot &vfunc, LoopPriority priority=LoopPriority::NORMAL)=0
Execute a signal callback for prepare, check, dispatch.
virtual bool iterate(bool block)=0
Perform one loop iteration and return whether more iterations are needed.
virtual bool finishable()=0
Indicates wether this loop has no primary sources left to process.
virtual LoopID add_source(LoopSourceP loop_source, LoopPriority priority=LoopPriority::NORMAL)=0
Adds a new source to the loop with custom priority.
virtual bool has_primary(void)=0
Indicates whether loop contains primary sources.
virtual bool exec_once(uint delay_ms, LoopID *once_id, const VoidSlot &vfunc, LoopPriority priority=LoopPriority::NORMAL)=0
Execute a callback once on SIGCHLD for pid.
static LoopP current()
Return the thread-local singleton loop, created on first call.
virtual void wakeup()=0
Wakeup loop from polling.
virtual bool pending()=0
Check if iterate() needs to be called for dispatching.
virtual void cancel(LoopID *idp)=0
Cancel a source by id if present and resets the id.
virtual bool running()=0
Indicates if quit() has been called already.
std::shared_ptr< Promise< Result > > make_promise(const std::function< void(std::function< void(Result)>)> &executor)
Create promise and immediately run executor.
virtual bool has_quit()=0
Check if quit() has been called.
Loop source for IO callbacks.
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Loop source for handler execution.
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Loop source for timer execution.
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
Loop source for handler execution.
virtual bool dispatch(const LoopState &state)
Dispatch source, returns if it should be kept alive.
virtual bool prepare(const LoopState &state, int64 *timeout_usecs_p)
Prepare the source for dispatching (true return) or polling (false).
static void raise(int8 signum)
Flag a unix signal being raised, this function may be called from any thread at any time.
virtual bool check(const LoopState &state)
Check the source and its PollFD descriptors for dispatching (true return).
Concept: Is T an awaitable?
T current_exception(T... args)
#define ASE_ASSERT_RETURN(expr,...)
Return from the current function if expr evaluates to false and issue an assertion warning.
#define ASE_DEFINE_MAKE_SHARED(CLASS)
Define a member function static shared_ptr<CLASS> make_shared(ctorargs...);.
#define ASE_ASSERT_WARN(expr)
Issue an assertion warning if expr evaluates to false.
#define ASE_CLASS_NON_COPYABLE(ClassName)
Delete copy ctor and assignment operator.
T make_exception_ptr(T... args)
The Anklang C++ API namespace.
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
int16_t int16
A 16-bit signed integer.
uint8_t uint8
An 8-bit unsigned integer.
int8_t int8
An 8-bit signed integer.
int64_t int64
A 64-bit unsigned integer, use PRI*64 in format strings.
@ NORMAL
Normal importantance, GUI event processing, RPC.
@ USIGNAL
Used for unix signal delivery.
@ LOW
Unimportant, used when everything else done.
@ NOTIFY
For async notification, delivery of change notifications.
@ IDLE
Mildly important, used for background tasks.
@ RTAUDIO
Threshold for priorization across different loops.
@ COAWAIT
Used for coroutines, continuations of functions.
@ SYSALLOC
Internal maintenance, don't use.
@ AFRAME
Animation frame timers, prioritized over normal event processing.
uint16_t uint16
A 16-bit unsigned integer.
uint32_t uint
Provide 'uint' as convenience type.
void ase_rethrow(std::exception_ptr exception)
Helper to trace rethrown exceptions.
T shared_from_this(T... args)
bool seen_primary
Useful as hint for primary source presence, MainLoop::finishable() checks exhaustively.
uint64 current_time_usecs
Equals timestamp_realtime() as of prepare() and check().
int64 timeout_usecs
Maximum timeout for poll, queried during prepare().
Helper to capture shared_ptr<Promise> to allow co_await on temporary Promise instances.
void resolve()
Resolve Promise<void>
void reject(std::exception_ptr exc=nullptr)
Reject promise with exception.
Mirrors struct pollfd for poll(3posix)
@ RDNORM
reading data will not block
@ HUP
file descriptor closed
@ WRNORM
writing data will not block
@ PRI
urgent data available
@ RDBAND
reading priority data will not block
@ OUT
writing data will not block
@ WRBAND
writing priority data will not block