JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
Loading...
Searching...
No Matches
jh::async::slot Class Referencefinal

Coroutine representing the user-defined asynchronous state machine. More...

#include <jh/asynchronous/slot.h>

Classes

struct  promise_type
 Slot coroutine promise type. More...

Public Member Functions

 slot ()=default
 Default constructor for slot.
 slot (slot &&o) noexcept
 Move constructor transferring coroutine handle ownership.
slotoperator= (slot &&o) noexcept
 Move assignment operator transferring coroutine handle ownership.
 slot (const slot &)=delete
 Copy constructor is deleted to prevent duplication of coroutine handle.
slotoperator= (const slot &)=delete
 Copy assignment is deleted to prevent unsafe copying of coroutine handle.
void spawn ()
 Start the coroutine associated with this slot.

Friends

template<typename T>
class listener
 Grants listener<T> access to internal slot members.

Detailed Description

Coroutine representing the user-defined asynchronous state machine.

A slot is the only execution context of the entire "slot-listener-signal" system. It defines the state machine, phase switching, routing, filtering, and fan-out logic. A slot always runs on the thread where spawn() is invoked.

Strong Synchronization Semantics

A slot may suspend on exactly one listener at any time. Each co_await represents one logical synchronous step.

Awaiting multiple listeners inside the same loop is technically idempotent per iteration but semantically meaningless, because this requires the external event sources to be strictly time-aligned. If external producers drift in timing (which is unavoidable in real-time systems), the synchronous semantics break immediately.

In other words, the following pattern is strongly discouraged:

auto a = co_await A;
auto b = co_await B;

This is irrelevant to our implementation. Semantically, asynchronous operations always perform triggering and consuming.

In other words, the discouraged behavior implies a sync-barrier semantic. This means that if any listener is advancing too rapidly and resumes two or more times before the other listener resumes even once in the same iteration, the state machine is broken.

According to the C++20 coroutine model, if you want to guarantee the correctness of this behavior, then you need external synchronization; that maps to sync-barrier rather than async-resuming.

However, If a user truly has perfectly time-aligned external timing, then the recommended design is:

  • Use one event_signal to emit a tuple containing all values needed for that round.
  • Do not await multiple listeners in the same phase.

In summary, this behavior is semantically determined and implementation-independent. If you need to observe multiple input sources in the same logical step, then it's fan-in, see listener.

Correct Usage of Multiple Listeners

Multiple listeners exist for different phases or different conditions, not for parallel waiting. A slot typically performs:

// Phase 1
for (;;) {
auto v = co_await listener_A;
if (v == STOP) break;
}
// Phase 2
for (;;) {
auto s = co_await listener_B;
}

Lifetime

  • Must not be moved after binding to a hub.
  • slot, slot_hub, and listeners must share unified lifetime.
Note
co_yield {} returns an empty sentinel value (jh::typed::monostate). This is not necessarily needed, but ensures consistency on non-main threads. It can also be used as a jump point (similar to return in a regular function).
Otherwise, the actual execution body is equivalent to the interval between the input co_await listener and the next declared co_await another_listener.

Member Function Documentation

◆ spawn()

void jh::async::slot::spawn ( )
inline

Start the coroutine associated with this slot.

Transitions the coroutine from the initial suspended state to active execution. It binds the coroutine to the current thread permanently. This function is only effective once.


The documentation for this class was generated from the following file:
  • include/jh/asynchronous/slot.h