boost::capy::Executor
Concept for types that schedule coroutine execution.
Synopsis
Declared in <boost/capy/concept/executor.hpp>
template<class E>
concept Executor = std::is_nothrow_copy_constructible_v<E> &&
std::is_nothrow_move_constructible_v<E> &&
requires(E& e, E const& ce, E const& ce2, std::coroutine_handle<> h) {
{ ce == ce2 } noexcept ‐> std::convertible_to<bool>;
{ ce.context() } noexcept;
requires std::is_lvalue_reference_v<decltype(ce.context())> &&
std::derived_from<
std::remove_reference_t<decltype(ce.context())>,
execution_context>;
{ ce.on_work_started() } noexcept;
{ ce.on_work_finished() } noexcept;
{ ce.dispatch(h) } ‐> std::same_as<std::coroutine_handle<>>;
{ ce.post(h) };
};
Description
An executor embodies a set of rules for determining how and where coroutines are executed. It provides operations to submit work and to track outstanding work for graceful shutdown.
Ordinary users writing coroutine tasks do not interact with dispatch and post directly. These operations are used by authors of coroutine machinery ‐‐ promise_type implementations, awaitables, await_transform ‐‐ to implement asynchronous algorithms such as when_all, when_any, async_mutex, channels, and similar primitives.
Syntactic Requirements
-
`E` must be nothrow copy and move constructible
-
`e1 == e2` must return a type convertible to `bool`, `noexcept`
-
`e.context()` must return an lvalue reference to a type derived from `execution_context`, `noexcept`
-
`e.on_work_started()` must be valid and `noexcept`
-
`e.on_work_finished()` must be valid and `noexcept`
-
`e.dispatch(h)` must return `std::coroutine_handle<>`
-
`e.post(h)` must be valid
Semantic Requirements
The context operation returns the owning context:
-
Returns a reference to the execution context that created this executor
-
The context outlives all executors created from it
The on_work_started and on_work_finished operations track work:
-
Calls must be paired; each `on_work_started` must have a matching `on_work_finished`
-
The context uses this count to determine when shutdown is complete
-
These are not intended for direct use by callers. They are public so that work guards can invoke them. This enables user‐defined guards with additional tracking behaviors, without the library needing to grant friendship to types it cannot anticipate
The dispatch operation returns a handle for symmetric transfer:
Every coroutine resumption must go through either symmetric transfer or the scheduler queue ‐‐ never through an inline resume() or dispatch() that creates a frame below the resumed coroutine.
-
If the executor determines it is safe to resume inline (e.g., already on the correct thread), returns `h` for the caller to use in symmetric transfer
-
Otherwise, posts the coroutine for later execution and returns `std::noop_coroutine()`
-
The caller is responsible for using the returned handle appropriately: returning it from `await_suspend` for symmetric transfer, or calling `.resume()` if at the event loop pump level
A conforming implementation might look like:
std::coroutine_handle<> dispatch(
std::coroutine_handle<> h ) const
{
if( ctx_.is_running_on_this_thread() )
return h; // symmetric transfer
post( h );
return std::noop_coroutine();
}
The post operation queues for later execution:
-
Never blocks the caller
-
The coroutine executes on the executor's associated context
Executor Validity
An executor becomes invalid when the first call to ctx.shutdown() returns. Calling dispatch, post, on_work_started, or on_work_finished on an invalid executor is undefined behavior. Copy, comparison, and context() remain valid until the context is destroyed.
Thread Safety
Distinct objects: Safe. Shared objects: Safe for copy, comparison, and context().
Conforming Signatures
class E
{
public:
execution_context& context() const noexcept;
void on_work_started() const noexcept;
void on_work_finished() const noexcept;
std::coroutine_handle<> dispatch(
std::coroutine_handle<> h ) const;
void post( std::coroutine_handle<> h ) const;
bool operator==( E const& ) const noexcept;
};
See Also
ExecutionContext, execution_context
Created with MrDocs