|
91 | 91 | \item |
92 | 92 | \tcode{err} if \tcode{decay_t<Err>} denotes the type \tcode{exception_ptr}. |
93 | 93 |
|
94 | | -\mandates |
95 | | -\tcode{err != exception_ptr()} is \tcode{true}. |
| 94 | +\expects |
| 95 | +\tcode{!err} is \tcode{false}. |
96 | 96 | \item |
97 | 97 | Otherwise, |
98 | 98 | \tcode{make_exception_ptr(system_error(err))} |
|
229 | 229 | representing the execution-time properties of the operation's caller. |
230 | 230 | The caller of an asynchronous operation is |
231 | 231 | its parent operation or the function that created it. |
232 | | -An asynchronous operation's operation state owns the operation's environment. |
233 | 232 |
|
234 | 233 | \pnum |
235 | 234 | An asynchronous operation has an associated receiver. |
|
1012 | 1011 | -> @\libconcept{same_as}@<remove_cvref_t<Sch>>; |
1013 | 1012 | } && |
1014 | 1013 | @\libconcept{equality_comparable}@<remove_cvref_t<Sch>> && |
1015 | | - @\libconcept{copy_constructible}@<remove_cvref_t<Sch>>; |
| 1014 | + @\libconcept{copyable}@<remove_cvref_t<Sch>>; |
1016 | 1015 | } |
1017 | 1016 | \end{codeblock} |
1018 | 1017 |
|
|
1025 | 1024 | shall be modeled. |
1026 | 1025 |
|
1027 | 1026 | \pnum |
1028 | | -None of a scheduler's |
1029 | | -copy constructor, |
1030 | | -destructor, |
1031 | | -equality comparison, or |
1032 | | -\tcode{swap} member functions |
| 1027 | +No operation required by |
| 1028 | +\tcode{\libconcept{copyable}<remove_cvref_t<Sch>>} and |
| 1029 | +\tcode{\libconcept{equality_comparable}<remove_cvref_t<Sch>>} |
1033 | 1030 | shall exit via an exception. |
1034 | | -None of these member functions, |
| 1031 | +None of these operations, |
1035 | 1032 | nor a scheduler type's \tcode{schedule} function, |
1036 | 1033 | shall introduce data races |
1037 | 1034 | as a result of potentially concurrent\iref{intro.races} invocations |
1038 | | -of those functions from different threads. |
| 1035 | +of those operations from different threads. |
1039 | 1036 |
|
1040 | 1037 | \pnum |
1041 | 1038 | For any two values \tcode{sch1} and \tcode{sch2} |
|
1727 | 1724 |
|
1728 | 1725 | \pnum |
1729 | 1726 | The expression in the \tcode{noexcept} clause of |
1730 | | -the constructor of \exposid{basic-state} is: |
| 1727 | +the constructor of \exposid{basic-state} is |
1731 | 1728 | \begin{codeblock} |
1732 | 1729 | is_nothrow_move_constructible_v<Rcvr> && |
1733 | | -@\exposconcept{nothrow-callable}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&> |
| 1730 | +@\exposconcept{nothrow-callable}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&> && |
| 1731 | +(same_as<@\exposid{state-type}@<Sndr, Rcvr>, @\exposid{get-state-result}@> || |
| 1732 | + is_nothrow_constructible_v<@\exposid{state-type}@<Sndr, Rcvr>, @\exposid{get-state-result}@>) |
| 1733 | +\end{codeblock} |
| 1734 | +where \exposid{get-state-result} is |
| 1735 | +\begin{codeblock} |
| 1736 | +@\exposid{call-result-t}@<decltype(@\exposid{impls-for}@<tag_of_t<Sndr>>::@\exposid{get-state}@), Sndr, Rcvr&>. |
1734 | 1737 | \end{codeblock} |
1735 | 1738 |
|
1736 | 1739 | \pnum |
|
1879 | 1882 | struct @\exposid{impls-for}@<@\exposid{write-env-t}@> : @\exposid{default-impls}@ { |
1880 | 1883 | static constexpr auto @\exposid{get-env}@ = |
1881 | 1884 | [](auto, const auto& state, const auto& rcvr) noexcept { |
1882 | | - return @\exposid{JOIN-ENV}@(state, get_env(rcvr)); |
| 1885 | + return @\seebelow@; |
1883 | 1886 | }; |
1884 | 1887 | }; |
1885 | 1888 | \end{codeblock} |
1886 | 1889 | \end{itemdescr} |
| 1890 | +Invocation of |
| 1891 | +\tcode{\exposid{impls-for}<\exposid{write-env-t}>::\exposid{get-env}} |
| 1892 | +returns an object \tcode{e} such that |
| 1893 | +\begin{itemize} |
| 1894 | +\item |
| 1895 | +\tcode{decltype(e)} models \exposconcept{queryable} and |
| 1896 | +\item |
| 1897 | +given a query object \tcode{q}, |
| 1898 | +the expression \tcode{e.query(q)} is expression-equivalent |
| 1899 | +to \tcode{state.query(q)} if that expression is valid, |
| 1900 | +otherwise, \tcode{e.query(q)} is expression-equivalent |
| 1901 | +to \tcode{get_env(rcvr).query(q)}. |
| 1902 | +\end{itemize} |
1887 | 1903 |
|
1888 | 1904 | \rSec2[exec.snd.concepts]{Sender concepts} |
1889 | 1905 |
|
|
2455 | 2471 | Let \exposid{operation-state-task} be the following exposition-only class: |
2456 | 2472 | \begin{codeblock} |
2457 | 2473 | namespace std::execution { |
2458 | | - struct @\exposid{operation-state-task}@ { |
| 2474 | + struct @\exposid{operation-state-task}@ { // \expos |
2459 | 2475 | using operation_state_concept = operation_state_t; |
2460 | 2476 | using promise_type = @\exposid{connect-awaitable-promise}@; |
2461 | 2477 |
|
2462 | 2478 | explicit @\exposid{operation-state-task}@(coroutine_handle<> h) noexcept : coro(h) {} |
2463 | | - @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&& o) noexcept |
2464 | | - : @\exposid{coro}@(exchange(o.@\exposid{coro}@, {})) {} |
2465 | | - ~@\exposid{operation-state-task}@() { if (@\exposid{coro}@) @\exposid{coro}@.destroy(); } |
| 2479 | + @\exposid{operation-state-task}@(@\exposid{operation-state-task}@&&) = delete; |
| 2480 | + ~@\exposid{operation-state-task}@() { @\exposid{coro}@.destroy(); } |
2466 | 2481 |
|
2467 | 2482 | void start() & noexcept { |
2468 | 2483 | @\exposid{coro}@.resume(); |
|
3053 | 3068 | using result_t = @\exposid{decayed-tuple}@<Tag, Args...>; |
3054 | 3069 | constexpr bool nothrow = is_nothrow_constructible_v<result_t, Tag, Args...>; |
3055 | 3070 |
|
3056 | | - @\exposid{TRY-EVAL}@(rcvr, [&]() noexcept(nothrow) { |
| 3071 | + try { |
3057 | 3072 | state.@\exposid{async-result}@.template emplace<result_t>(Tag(), std::forward<Args>(args)...); |
3058 | | - }()); |
3059 | | - |
3060 | | - if (state.@\exposid{async-result}@.valueless_by_exception()) |
3061 | | - return; |
3062 | | - if (state.@\exposid{async-result}@.index() == 0) |
3063 | | - return; |
3064 | | - |
| 3073 | + } catch (...) { |
| 3074 | + if constexpr (!nothrow) { |
| 3075 | + set_error(std::move(rcvr), current_exception()); |
| 3076 | + return; |
| 3077 | + } |
| 3078 | + } |
3065 | 3079 | start(state.@\exposid{op-state}@); |
3066 | 3080 | }; |
3067 | 3081 | \end{codeblock} |
|
3448 | 3462 | } |
3449 | 3463 |
|
3450 | 3464 | decltype(auto) get_env() const noexcept { |
3451 | | - return @\exposid{JOIN-ENV}@(@\exposid{env}@, @\exposid{FWD-ENV}@(execution::get_env(@\exposid{rcvr}@))); |
| 3465 | + return @\seebelow@; |
3452 | 3466 | } |
3453 | 3467 |
|
3454 | 3468 | Rcvr& @\exposid{rcvr}@; // \expos |
3455 | 3469 | Env @\exposid{env}@; // \expos |
3456 | 3470 | }; |
3457 | 3471 | } |
3458 | 3472 | \end{codeblock} |
| 3473 | +Invocation of the function \tcode{\exposid{receiver2}::get_env} |
| 3474 | +returns an object \tcode{e} such that |
| 3475 | +\begin{itemize} |
| 3476 | +\item |
| 3477 | +\tcode{decltype(e)} models \exposconcept{queryable} and |
| 3478 | +\item |
| 3479 | +given a query object \tcode{q}, |
| 3480 | +the expression \tcode{e.query(q)} is expression-equivalent |
| 3481 | +to \tcode{\exposid{env}.query(q)} if that expression is valid, |
| 3482 | +otherwise \tcode{e.query(q)} is expression-equivalent |
| 3483 | +to \tcode{get_env(\exposid{rcvr}).query(q)}. |
| 3484 | +\end{itemize} |
3459 | 3485 |
|
3460 | 3486 | \pnum |
3461 | 3487 | \tcode{\exposid{impls-for}<\exposid{decayed-typeof}<\exposid{let-cpo}>>::\exposid{get-state}} |
|
3647 | 3673 | \item |
3648 | 3674 | on a value completion operation, |
3649 | 3675 | invokes \tcode{f(i, args...)} |
3650 | | -for every \tcode{i} of type \tcode{Shape} from \tcode{0} to \tcode{shape}, |
| 3676 | +for every \tcode{i} of type \tcode{Shape} in \range{\tcode{0}}{\tcode{shape}}, |
3651 | 3677 | where \tcode{args} is a pack of lvalue subexpressions |
3652 | 3678 | referring to the value completion result datums of the input sender, and |
3653 | 3679 | \item |
|
4101 | 4127 | equivalent to the following lambda expression: |
4102 | 4128 | \begin{codeblock} |
4103 | 4129 | []<class State, class Rcvr>(auto&&, State& state, const Receiver& rcvr) noexcept { |
4104 | | - return @\exposid{JOIN-ENV}@( |
4105 | | - @\exposid{MAKE-ENV}@(get_stop_token, state.@\exposid{stop_src}@.get_token()), get_env(rcvr)); |
| 4130 | + return @\seebelow@; |
4106 | 4131 | } |
4107 | 4132 | \end{codeblock} |
| 4133 | +Returns an object \tcode{e} such that |
| 4134 | +\begin{itemize} |
| 4135 | +\item |
| 4136 | +\tcode{decltype(e)} models \exposconcept{queryable}, and |
| 4137 | +\item |
| 4138 | +\tcode{e.query(get_stop_token)} is expression-equivalent to |
| 4139 | +\tcode{state.\exposid{stop-src}.get_token()}, and |
| 4140 | +\item |
| 4141 | +given a query object \tcode{q} with type other than \cv{} \tcode{stop_token_t}, |
| 4142 | +\tcode{e.query(q)} is expression-equivalent to \tcode{get_env(rcvr).query(q)}. |
| 4143 | +\end{itemize} |
4108 | 4144 |
|
4109 | 4145 | \pnum |
4110 | 4146 | The member \tcode{\exposid{impls-for}<when_all_t>::\exposid{get-state}} |
|
4957 | 4993 | A \tcode{run_loop} instance has an associated \defn{count} |
4958 | 4994 | that corresponds to the number of work items that are in its queue. |
4959 | 4995 | Additionally, a \tcode{run_loop} instance has an associated state |
4960 | | -that can be one of \defn{starting}, \defn{running}, or \defn{finishing}. |
| 4996 | +that can be one of |
| 4997 | +\defn{starting}, \defn{running}, \defn{finishing}, or \defn{finished}. |
4961 | 4998 |
|
4962 | 4999 | \pnum |
4963 | 5000 | Concurrent invocations of the member functions of \tcode{run_loop} |
|
5146 | 5183 | \begin{itemize} |
5147 | 5184 | \item |
5148 | 5185 | \exposid{count} is \tcode{0} and \exposid{state} is \exposid{finishing}, |
5149 | | -in which case \exposid{pop-front} returns \tcode{nullptr}; or |
| 5186 | +in which case \exposid{pop-front} sets \exposid{state} to \exposid{finished} |
| 5187 | +and returns \tcode{nullptr}; or |
5150 | 5188 | \item |
5151 | 5189 | \exposid{count} is greater than \tcode{0}, |
5152 | 5190 | in which case an item is removed from the front of the queue, |
|
5191 | 5229 | \begin{itemdescr} |
5192 | 5230 | \pnum |
5193 | 5231 | \expects |
5194 | | -\exposid{state} is \exposid{starting}. |
| 5232 | +\exposid{state} is either \exposid{starting} or \exposid{finishing}. |
5195 | 5233 |
|
5196 | 5234 | \pnum |
5197 | 5235 | \effects |
5198 | | -Sets the \exposid{state} to \exposid{running}. Then, equivalent to: |
| 5236 | +If \exposid{state} is \exposid{starting}, |
| 5237 | +sets the \exposid{state} to \exposid{running}, |
| 5238 | +otherwise leaves \exposid{state} unchanged. |
| 5239 | +Then, equivalent to: |
5199 | 5240 | \begin{codeblock} |
5200 | 5241 | while (auto* op = @\exposid{pop-front}@()) { |
5201 | 5242 | op->@\exposid{execute}@(); |
|
5213 | 5254 | \end{itemdecl} |
5214 | 5255 |
|
5215 | 5256 | \begin{itemdescr} |
| 5257 | +\pnum |
| 5258 | +\expects |
| 5259 | +\exposid{state} is either \exposid{starting} or \exposid{running}. |
| 5260 | + |
5216 | 5261 | \pnum |
5217 | 5262 | \effects |
5218 | 5263 | Changes \exposid{state} to \exposid{finishing}. |
|
0 commit comments