Async

Strand, on-strand helper, trampoline, timer, and registry utilities.

ua::async::Registry

class

A thread-safe registry of long-lived shared components keyed by id.

Wraps a std::unordered_map<Id, std::shared_ptr<T>> behind a std::shared_mutex, offering only insert / lookup / remove / enumerate. It is the canonical container for long-lived components. Domain logic (eviction policy, telemetry, dispatch) belongs on the layer that owns the registry, never on the registry itself; per-component subclassing is not used.

All member functions are safe to call concurrently from any thread: mutating operations take a unique lock and lookups/enumeration take a shared lock. Entries are held by shared_ptr, so a value obtained from lookup or enumerate stays alive even after it is removed from the registry.

Id Key type. Must be hashable (std::hash<Id>) and equality-comparable. T Mapped component type; stored and handed out as std::shared_ptr<T>.

Functions

Registry()=default

Constructs an empty registry.

std::shared_ptr< T > insert(Id id, std::shared_ptr< T > entry)

Inserts an entry under id unless id is already present.

  • id (Id) - Key to insert under; moved from.
  • entry (std::shared_ptr< T >) - Component to store; moved from. Discarded on collision.

Returns: The entry stored at id after the call - the just-inserted entry on success, or the pre-existing entry on collision.

std::shared_ptr< T > lookup(const Id &id) const

Returns the entry stored at id, or nullptr if absent.

  • id (const Id &) - Key to look up.

Returns: The entry stored at id, or nullptr if none is present.

void remove(const Id &id)

Removes the entry at id; a no-op if id is absent.

  • id (const Id &) - Key whose entry to remove.
std::vector< std::shared_ptr< T > > enumerate() const

Returns a snapshot of all entries in unspecified order.

Returns: Every entry present at the moment the snapshot was taken.

ua::Timer

class

A move-only RAII timer bound to an Asio executor.

Constructed only through the static factories schedule_after (one-shot) and schedule_every (periodic), each of which arms a timer on the given executor - typically a strand, in which case the notifier is serialized with that strand's other work. A default-constructed Timer is empty (holds no armed timer) and contextually converts to false. Destruction or cancel stops an armed timer; moving transfers ownership of the armed state.

Executor lifetime: the executor passed to schedule_after / schedule_every must outlive the returned Timer. This is Asio's universal contract for I/O objects - destroying the executor's underlying io_context / thread_pool while a Timer is still alive is undefined behaviour and may leak or use-after-free inside Asio internals.

Fixed-grid framing: schedule_every fires on a fixed phase grid of stride period. If the notifier returns later than the next scheduled fire, slots already in the past are skipped - the grid is never phase-shifted to now + period, and missed slots are never coalesced into a burst.

Member types

std::function< void(boost::system::error_code)> Notifier

Notifier invoked on each expiry, on the bound executor.

Static functions

Timer schedule_after(boost::asio::any_io_executor executor, std::chrono::steady_clock::duration delay, Notifier notifier)

Arms a one-shot timer that fires once after delay.

  • executor (boost::asio::any_io_executor) - Executor the notifier runs on; must outlive the returned timer (see executor-lifetime note on Timer).
  • delay (std::chrono::steady_clock::duration) - Duration from now until the single expiry.
  • notifier (Notifier) - Invoked once on expiry. NOT invoked if the timer is cancelled or destroyed first - cancellation is final and delivers no callback at all (see cancel).

Returns: An armed timer; let it expire, or cancel/destroy it to stop.

Timer schedule_every(boost::asio::any_io_executor executor, std::chrono::steady_clock::duration period, Notifier notifier)

Arms a periodic timer that fires repeatedly on a fixed grid of stride period.

  • executor (boost::asio::any_io_executor) - Executor the notifier runs on; must outlive the returned timer (see executor-lifetime note on Timer).
  • period (std::chrono::steady_clock::duration) - Stride between successive grid slots.
  • notifier (Notifier) - Invoked on each expiry. NOT invoked when the timer is cancelled or destroyed - cancellation is final and delivers no callback at all (see cancel).

Returns: An armed periodic timer; cancel or destroy it to stop the schedule.

Functions

Timer()=default

Constructs an empty timer that holds no armed wait and converts to false.

~Timer()

Cancels any armed timer.

Timer(Timer &&other) noexcept

Transfers the armed state; the moved-from timer becomes empty.

  • other (Timer &&) - The timer whose armed state is transferred.
Timer & operator=(Timer &&other) noexcept

Transfers the armed state, cancelling any timer this object already held; the moved-from timer becomes empty.

  • other (Timer &&) - The timer whose armed state is transferred.

Returns: Reference to this timer.

void cancel()

Cancels the armed timer, if any, and leaves this object empty.

operator bool() const noexcept

Returns true while this object holds an armed timer.

Was this page helpful?