From Jason Turner

[exec.sync.wait]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpzpahqgut/{from.md → to.md} +154 -0
tmp/tmpzpahqgut/{from.md → to.md} RENAMED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### `this_thread::sync_wait` <a id="exec.sync.wait">[[exec.sync.wait]]</a>
2
+
3
+ `this_thread::sync_wait` and `this_thread::sync_wait_with_variant` are
4
+ used to block the current thread of execution until the specified sender
5
+ completes and to return its async result. `sync_wait` mandates that the
6
+ input sender has exactly one value completion signature.
7
+
8
+ Let *`sync-wait-env`* be the following exposition-only class type:
9
+
10
+ ``` cpp
11
+ namespace std::this_thread {
12
+ struct sync-wait-env {
13
+ execution::run_loop* loop; // exposition only
14
+
15
+ auto query(execution::get_scheduler_t) const noexcept {
16
+ return loop->get_scheduler();
17
+ }
18
+
19
+ auto query(execution::get_delegation_scheduler_t) const noexcept {
20
+ return loop->get_scheduler();
21
+ }
22
+ };
23
+ }
24
+ ```
25
+
26
+ Let *`sync-wait-result-type`* and *`sync-wait-with-variant-result-type`*
27
+ be exposition-only alias templates defined as follows:
28
+
29
+ ``` cpp
30
+ namespace std::this_thread {
31
+ template<execution::sender_in<sync-wait-env> Sndr>
32
+ using sync-wait-result-type =
33
+ optional<execution::value_types_of_t<Sndr, sync-wait-env, decayed-tuple,
34
+ type_identity_t>>;
35
+
36
+ template<execution::sender_in<sync-wait-env> Sndr>
37
+ using sync-wait-with-variant-result-type =
38
+ optional<execution::value_types_of_t<Sndr, sync-wait-env>>;
39
+ }
40
+ ```
41
+
42
+ The name `this_thread::sync_wait` denotes a customization point object.
43
+ For a subexpression `sndr`, let `Sndr` be `decltype((sndr))`. The
44
+ expression `this_thread::sync_wait(sndr)` is expression-equivalent to
45
+ the following, except that `sndr` is evaluated only once:
46
+
47
+ ``` cpp
48
+ apply_sender(get-domain-early(sndr), sync_wait, sndr)
49
+ ```
50
+
51
+ *Mandates:*
52
+
53
+ - `sender_in<Sndr, sync-wait-env>` is `true`.
54
+ - The type `sync-wait-result-type<Sndr>` is well-formed.
55
+ - `same_as<decltype(e), sync-wait-result-type<Sndr>>` is `true`, where e
56
+ is the `apply_sender` expression above.
57
+
58
+ Let *`sync-wait-state`* and *`sync-wait-receiver`* be the following
59
+ exposition-only class templates:
60
+
61
+ ``` cpp
62
+ namespace std::this_thread {
63
+ template<class Sndr>
64
+ struct sync-wait-state { // exposition only
65
+ execution::run_loop loop; // exposition only
66
+ exception_ptr error; // exposition only
67
+ sync-wait-result-type<Sndr> result; // exposition only
68
+ };
69
+
70
+ template<class Sndr>
71
+ struct sync-wait-receiver { // exposition only
72
+ using receiver_concept = execution::receiver_t;
73
+ sync-wait-state<Sndr>* state; // exposition only
74
+
75
+ template<class... Args>
76
+ void set_value(Args&&... args) && noexcept;
77
+
78
+ template<class Error>
79
+ void set_error(Error&& err) && noexcept;
80
+
81
+ void set_stopped() && noexcept;
82
+
83
+ sync-wait-env get_env() const noexcept { return {&state->loop}; }
84
+ };
85
+ }
86
+ ```
87
+
88
+ ``` cpp
89
+ template<class... Args>
90
+ void set_value(Args&&... args) && noexcept;
91
+ ```
92
+
93
+ *Effects:* Equivalent to:
94
+
95
+ ``` cpp
96
+ try {
97
+ state->result.emplace(std::forward<Args>(args)...);
98
+ } catch (...) {
99
+ state->error = current_exception();
100
+ }
101
+ state->loop.finish();
102
+ ```
103
+
104
+ ``` cpp
105
+ template<class Error>
106
+ void set_error(Error&& err) && noexcept;
107
+ ```
108
+
109
+ *Effects:* Equivalent to:
110
+
111
+ ``` cpp
112
+ state->error = AS-EXCEPT-PTR(std::forward<Error>(err)); // see [exec.general]
113
+ state->loop.finish();
114
+ ```
115
+
116
+ ``` cpp
117
+ void set_stopped() && noexcept;
118
+ ```
119
+
120
+ *Effects:* Equivalent to *`state`*`->`*`loop`*`.finish()`.
121
+
122
+ For a subexpression `sndr`, let `Sndr` be `decltype((sndr))`. If
123
+ `sender_to<Sndr, sync-wait-receiver<Sndr>>` is `false`, the expression
124
+ `sync_wait.apply_sender(sndr)` is ill-formed; otherwise, it is
125
+ equivalent to:
126
+
127
+ ``` cpp
128
+ sync-wait-state<Sndr> state;
129
+ auto op = connect(sndr, sync-wait-receiver<Sndr>{&state});
130
+ start(op);
131
+
132
+ state.loop.run();
133
+ if (state.error) {
134
+ rethrow_exception(std::move(state.error));
135
+ }
136
+ return std::move(state.result);
137
+ ```
138
+
139
+ The behavior of `this_thread::sync_wait(sndr)` is undefined unless:
140
+
141
+ - It blocks the current thread of execution [[defns.block]] with forward
142
+ progress guarantee delegation [[intro.progress]] until the specified
143
+ sender completes. \[*Note 1*: The default implementation of
144
+ `sync_wait` achieves forward progress guarantee delegation by
145
+ providing a `run_loop` scheduler via the `get_delegation_scheduler`
146
+ query on the *`sync-wait-receiver`*’s environment. The `run_loop` is
147
+ driven by the current thread of execution. — *end note*]
148
+ - It returns the specified sender’s async results as follows:
149
+ - For a value completion, the result datums are returned in a `tuple`
150
+ in an engaged `optional` object.
151
+ - For an error completion, an exception is thrown.
152
+ - For a stopped completion, a disengaged `optional` object is
153
+ returned.
154
+