6.5 KiB
[exec.sync.wait]
33 Execution control library [exec]
33.9 Senders [exec.snd]
33.9.13 Sender consumers [exec.consumers]
33.9.13.1 this_thread::sync_wait [exec.sync.wait]
this_thread::sync_wait and this_thread::sync_wait_with_variant are used to block the current thread of execution until the specified sender completes and to return its async result.
sync_wait mandates that the input sender has exactly one value completion signature.
Let sync-wait-env be the following exposition-only class type:namespace std::this_thread {struct sync-wait-env { execution::run_loop* loop; // exposition onlyauto query(execution::get_scheduler_t) const noexcept {return loop->get_scheduler(); }auto query(execution::get_delegation_scheduler_t) const noexcept {return loop->get_scheduler(); }};}
Let sync-wait-result-type andsync-wait-with-variant-result-type be exposition-only alias templates defined as follows:namespace std::this_thread {template<execution::sender_in<sync-wait-env> Sndr>using sync-wait-result-type = optional<execution::value_types_of_t<Sndr, sync-wait-env, decayed-tuple, type_identity_t>>; template<execution::sender_in<sync-wait-env> Sndr>using sync-wait-with-variant-result-type = optional<execution::value_types_of_t<Sndr, sync-wait-env>>;}
The name this_thread::sync_wait denotes a customization point object.
For a subexpression sndr, let Sndr be decltype((sndr)).
The expression this_thread::sync_wait(sndr) is expression-equivalent to the following, except that sndr is evaluated only once:apply_sender(get-domain-early(sndr), sync_wait, sndr)Mandates:
-
The type sync-wait-result-type is well-formed.
-
same_as<decltype(e), sync-wait-result-type> is true, where e is the apply_sender expression above.
Let sync-wait-state and sync-wait-receiver be the following exposition-only class templates:namespace std::this_thread {templatestruct sync-wait-state { // exposition only execution::run_loop loop; // exposition only exception_ptr error; // exposition only**sync-wait-result-type result; // exposition only}; templatestruct sync-wait-receiver { // exposition onlyusing receiver_concept = execution::receiver_t; sync-wait-state* state; // exposition onlytemplate<class... Args>void set_value(Args&&... args) && noexcept; templatevoid set_error(Error&& err) && noexcept; void set_stopped() && noexcept; sync-wait-env get_env() const noexcept { return {&state->loop}; }};}
template<class... Args> void set_value(Args&&... args) && noexcept;
Effects: Equivalent to:try {state->result.emplace(std::forward(args)...);} catch (...) {state->error = current_exception();}state->loop.finish();
template<class Error> void set_error(Error&& err) && noexcept;
Effects: Equivalent to:state->error = AS-EXCEPT-PTR(std::forward(err)); // see [exec.general]state->loop.finish();
void set_stopped() && noexcept;
Effects: Equivalent to state->loop.finish().
For a subexpression sndr, let Sndr be decltype((sndr)).
If sender_to<Sndr, sync-wait-receiver> is false, the expression sync_wait.apply_sender(sndr) is ill-formed; otherwise, it is equivalent to:sync-wait-state state;auto op = connect(sndr, sync-wait-receiver{&state}); start(op);
state.loop.run();if (state.error) { rethrow_exception(std::move(state.error));}return std::move(state.result);
The behavior of this_thread::sync_wait(sndr) is undefined unless:
-
It blocks the current thread of execution ([defns.block]) with forward progress guarantee delegation ([intro.progress]) until the specified sender completes. [Note 1: The default implementation of sync_wait achieves forward progress guarantee delegation by providing a run_loop scheduler via the get_delegation_scheduler query on the sync-wait-receiver's environment. The run_loop is driven by the current thread of execution. â end note]
-
It returns the specified sender's async results as follows: