From Jason Turner

[exec.on]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp2zeg3cpk/{from.md → to.md} +156 -0
tmp/tmp2zeg3cpk/{from.md → to.md} RENAMED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #### `execution::on` <a id="exec.on">[[exec.on]]</a>
2
+
3
+ The `on` sender adaptor has two forms:
4
+
5
+ - `on(sch, sndr)`, which starts a sender `sndr` on an execution agent
6
+ belonging to a scheduler `sch`’s associated execution resource and
7
+ that, upon `sndr`’s completion, transfers execution back to the
8
+ execution resource on which the `on` sender was started.
9
+ - `on(sndr, sch, closure)`, which upon completion of a sender `sndr`,
10
+ transfers execution to an execution agent belonging to a scheduler
11
+ `sch`’s associated execution resource, then executes a sender adaptor
12
+ closure `closure` with the async results of the sender, and that then
13
+ transfers execution back to the execution resource on which `sndr`
14
+ completed.
15
+
16
+ The name `on` denotes a pipeable sender adaptor object. For
17
+ subexpressions `sch` and `sndr`, `on(sch, sndr)` is ill-formed if any of
18
+ the following is `true`:
19
+
20
+ - `decltype((sch))` does not satisfy `scheduler`, or
21
+ - `decltype((sndr))` does not satisfy `sender` and `sndr` is not a
22
+ pipeable sender adaptor closure object [[exec.adapt.obj]], or
23
+ - `decltype((sndr))` satisfies `sender` and `sndr `is also a pipeable
24
+ sender adaptor closure object.
25
+
26
+ Otherwise, if `decltype((sndr))` satisfies `sender`, the expression
27
+ `on(sch, sndr)` is expression-equivalent to:
28
+
29
+ ``` cpp
30
+ transform_sender(
31
+ query-with-default(get_domain, sch, default_domain()),
32
+ make-sender(on, sch, sndr))
33
+ ```
34
+
35
+ except that `sch` is evaluated only once.
36
+
37
+ For subexpressions `sndr`, `sch`, and `closure`, if
38
+
39
+ - `decltype((sch))` does not satisfy `scheduler`, or
40
+ - `decltype((sndr))` does not satisfy `sender`, or
41
+ - `closure` is not a pipeable sender adaptor closure object
42
+ [[exec.adapt.obj]],
43
+
44
+ the expression `on(sndr, sch, closure)` is ill-formed; otherwise, it is
45
+ expression-equivalent to:
46
+
47
+ ``` cpp
48
+ transform_sender(
49
+ get-domain-early(sndr),
50
+ make-sender(on, product-type{sch, closure}, sndr))
51
+ ```
52
+
53
+ except that `sndr` is evaluated only once.
54
+
55
+ Let `out_sndr` and `env` be subexpressions, let `OutSndr` be
56
+ `decltype((out_sndr))`, and let `Env` be `decltype((env))`. If
57
+ `sender-for<OutSndr, on_t>` is `false`, then the expressions
58
+ `on.transform_env(out_sndr, env)` and
59
+ `on.transform_sender(out_sndr, env)` are ill-formed.
60
+
61
+ Otherwise: Let *`not-a-scheduler`* be an unspecified empty class type.
62
+
63
+ The expression `on.transform_env(out_sndr, env)` has effects equivalent
64
+ to:
65
+
66
+ ``` cpp
67
+ auto&& [_, data, _] = out_sndr;
68
+ if constexpr (scheduler<decltype(data)>) {
69
+ return JOIN-ENV(SCHED-ENV(std::forward_like<OutSndr>(data)), FWD-ENV(std::forward<Env>(env)));
70
+ } else {
71
+ return std::forward<Env>(env);
72
+ }
73
+ ```
74
+
75
+ The expression `on.transform_sender(out_sndr, env)` has effects
76
+ equivalent to:
77
+
78
+ ``` cpp
79
+ auto&& [_, data, child] = out_sndr;
80
+ if constexpr (scheduler<decltype(data)>) {
81
+ auto orig_sch =
82
+ query-with-default(get_scheduler, env, not-a-scheduler());
83
+
84
+ if constexpr (same_as<decltype(orig_sch), not-a-scheduler>) {
85
+ return not-a-sender{};
86
+ } else {
87
+ return continues_on(
88
+ starts_on(std::forward_like<OutSndr>(data), std::forward_like<OutSndr>(child)),
89
+ std::move(orig_sch));
90
+ }
91
+ } else {
92
+ auto& [sch, closure] = data;
93
+ auto orig_sch = query-with-default(
94
+ get_completion_scheduler<set_value_t>,
95
+ get_env(child),
96
+ query-with-default(get_scheduler, env, not-a-scheduler()));
97
+
98
+ if constexpr (same_as<decltype(orig_sch), not-a-scheduler>) {
99
+ return not-a-sender{};
100
+ } else {
101
+ return write_env(
102
+ continues_on(
103
+ std::forward_like<OutSndr>(closure)(
104
+ continues_on(
105
+ write_env(std::forward_like<OutSndr>(child), SCHED-ENV(orig_sch)),
106
+ sch)),
107
+ orig_sch),
108
+ SCHED-ENV(sch));
109
+ }
110
+ }
111
+ ```
112
+
113
+ Let `out_sndr` be a subexpression denoting a sender returned from
114
+ `on(sch, sndr)` or one equal to such, and let `OutSndr` be the type
115
+ `decltype((out_sndr))`. Let `out_rcvr` be a subexpression denoting a
116
+ receiver that has an environment of type `Env` such that
117
+ `sender_in<OutSndr, Env>` is `true`. Let `op` be an lvalue referring to
118
+ the operation state that results from connecting `out_sndr` with
119
+ `out_rcvr`. Calling `start(op)` shall
120
+
121
+ - remember the current scheduler, `get_scheduler(get_env(rcvr))`;
122
+ - start `sndr` on an execution agent belonging to `sch`’s associated
123
+ execution resource;
124
+ - upon `sndr`’s completion, transfer execution back to the execution
125
+ resource associated with the scheduler remembered in step 1; and
126
+ - forward `sndr`’s async result to `out_rcvr`.
127
+
128
+ If any scheduling operation fails, an error completion on `out_rcvr`
129
+ shall be executed on an unspecified execution agent.
130
+
131
+ Let `out_sndr` be a subexpression denoting a sender returned from
132
+ `on(sndr, sch, closure)` or one equal to such, and let `OutSndr` be the
133
+ type `decltype((out_sndr))`. Let `out_rcvr` be a subexpression denoting
134
+ a receiver that has an environment of type `Env` such that
135
+ `sender_in<OutSndr, Env>` is `true`. Let `op` be an lvalue referring to
136
+ the operation state that results from connecting `out_sndr` with
137
+ `out_rcvr`. Calling `start(op)` shall
138
+
139
+ - remember the current scheduler, which is the first of the following
140
+ expressions that is well-formed:
141
+ - `get_completion_scheduler<set_value_t>(get_env(sndr))`
142
+ - `get_scheduler(get_env(rcvr))`;
143
+ - start `sndr` on the current execution agent;
144
+ - upon `sndr`’s completion, transfer execution to an agent owned by
145
+ `sch`’s associated execution resource;
146
+ - forward `sndr`’s async result as if by connecting and starting a
147
+ sender `closure(S)`, where `S` is a sender that completes
148
+ synchronously with `sndr`’s async result; and
149
+ - upon completion of the operation started in the previous step,
150
+ transfer execution back to the execution resource associated with the
151
+ scheduler remembered in step 1 and forward the operation’s async
152
+ result to `out_rcvr`.
153
+
154
+ If any scheduling operation fails, an error completion on `out_rcvr`
155
+ shall be executed on an unspecified execution agent.
156
+