Files
2025-10-25 03:02:53 +03:00

148 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[exec.sync.wait]
# 33 Execution control library [[exec]](./#exec)
## 33.9 Senders [[exec.snd]](exec.snd#exec.sync.wait)
### 33.9.13 Sender consumers [[exec.consumers]](exec.consumers#exec.sync.wait)
#### 33.9.13.1 this_thread::sync_wait [exec.sync.wait]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5595)
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[.](#1.sentence-1)
sync_wait mandates
that the input sender has exactly one value completion signature[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5604)
Let *sync-wait-env* be the following exposition-only class type:namespace std::this_thread {struct *sync-wait-env* { execution::run_loop* *loop*; // *exposition only*auto query(execution::get_scheduler_t) const noexcept {return *loop*->get_scheduler(); }auto query(execution::get_delegation_scheduler_t) const noexcept {return *loop*->get_scheduler(); }};}
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5622)
Let *sync-wait-result-type* and*sync-wait-with-variant-result-type* be exposition-only alias templates defined as follows:namespace std::this_thread {template<execution::[sender_in](exec.snd.concepts#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<*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](exec.snd.concepts#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<*sync-wait-env*> Sndr>using *sync-wait-with-variant-result-type* = optional<execution::value_types_of_t<Sndr, *sync-wait-env*>>;}
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5639)
The name this_thread::sync_wait denotes a customization point object[.](#4.sentence-1)
For a subexpression sndr, let Sndr be decltype((sndr))[.](#4.sentence-2)
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*:
- [(4.1)](#4.1)
[sender_in](exec.snd.concepts#concept:sender_in "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, *sync-wait-env*> is true[.](#4.1.sentence-1)
- [(4.2)](#4.2)
The type *sync-wait-result-type*<Sndr> is well-formed[.](#4.2.sentence-1)
- [(4.3)](#4.3)
[same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<decltype(e), *sync-wait-result-type*<Sndr>> is true, where e is the apply_sender expression above[.](#4.3.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5659)
Let *sync-wait-state* and *sync-wait-receiver* be the following exposition-only class templates:namespace std::this_thread {template<class Sndr>struct *sync-wait-state* { // *exposition only* execution::run_loop *loop*; // *exposition only* exception_ptr *error*; // *exposition only**sync-wait-result-type*<Sndr> *result*; // *exposition only*}; template<class Sndr>struct *sync-wait-receiver* { // *exposition only*using receiver_concept = execution::receiver_t; *sync-wait-state*<Sndr>* *state*; // *exposition only*template<class... Args>void set_value(Args&&... args) && noexcept; template<class Error>void set_error(Error&& err) && noexcept; void set_stopped() && noexcept; *sync-wait-env* get_env() const noexcept { return {&*state*->*loop*}; }};}
[🔗](#itemdecl:1)
`template<class... Args>
void set_value(Args&&... args) && noexcept;
`
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5695)
*Effects*: Equivalent to:try {*state*->*result*.emplace(std::forward<Args>(args)...);} catch (...) {*state*->*error* = current_exception();}*state*->*loop*.finish();
[🔗](#itemdecl:2)
`template<class Error>
void set_error(Error&& err) && noexcept;
`
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5714)
*Effects*: Equivalent to:*state*->*error* = *AS-EXCEPT-PTR*(std::forward<Error>(err)); // see [[exec.general]](exec.general "33.1General")*state*->*loop*.finish();
[🔗](#itemdecl:3)
`void set_stopped() && noexcept;
`
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5728)
*Effects*: Equivalent to *state*->*loop*.finish()[.](#8.sentence-1)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5733)
For a subexpression sndr, let Sndr be decltype((sndr))[.](#9.sentence-1)
If [sender_to](exec.snd.concepts#concept:sender_to "33.9.3Sender concepts[exec.snd.concepts]")<Sndr, *sync-wait-receiver*<Sndr>> is false,
the expression sync_wait.apply_sender(sndr) is ill-formed;
otherwise, it is equivalent to:*sync-wait-state*<Sndr> state;auto op = connect(sndr, *sync-wait-receiver*<Sndr>{&state});
start(op);
state.*loop*.run();if (state.*error*) { rethrow_exception(std::move(state.*error*));}return std::move(state.*result*);
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/exec.tex#L5751)
The behavior of this_thread::sync_wait(sndr) is undefined unless:
- [(10.1)](#10.1)
It blocks the current thread of execution ([[defns.block]](defns.block "3.6block"))
with forward progress guarantee delegation ([[intro.progress]](intro.progress "6.10.2.3Forward progress"))
until the specified sender completes[.](#10.1.sentence-1)
[*Note [1](#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[.](#10.1.sentence-2)
The run_loop is driven by the current thread of execution[.](#10.1.sentence-3)
— *end note*]
- [(10.2)](#10.2)
It returns the specified sender's async results as follows:
* [(10.2.1)](#10.2.1)
For a value completion,
the result datums are returned in
a tuple in an engaged optional object[.](#10.2.1.sentence-1)
* [(10.2.2)](#10.2.2)
For an error completion, an exception is thrown[.](#10.2.2.sentence-1)
* [(10.2.3)](#10.2.3)
For a stopped completion, a disengaged optional object is returned[.](#10.2.3.sentence-1)