From 7daa09f77a390d546ff5748be0ced6ca09acdbde Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Wed, 1 May 2024 14:59:23 -0700 Subject: [PATCH] LWG feedback from the 2024-05-01 telecon --- execution.bs | 165 +++++++++++++++++++++++++-------------------------- 1 file changed, 81 insertions(+), 84 deletions(-) diff --git a/execution.bs b/execution.bs index 50e7bd3..ad586c7 100644 --- a/execution.bs +++ b/execution.bs @@ -4278,69 +4278,67 @@ Header `` synopsis [thread.stoptoken.syn] and Class 2. An object of type `SCB` has an associated callback function of type `CallbackFn`. Let `scb` be an object of type `SCB` - and let `cbfn` denote `scb`'s associated callback function. + and let `callback_fn` denote `scb`'s associated callback function. Direct-non-list-initializing `scb` from arguments `t` and `init` shall execute a stoppable callback registration as follows: 1. If `t.stop_possible()` is `true`: - 1. `cbfn` shall be direct-initialized with `init`. + 1. `callback_fn` shall be direct-initialized with `init`. 2. Construction of `scb` shall only throw exceptions thrown by the - initialization of `cbfn` from `init`. + initialization of `callback_fn` from `init`. - 3. The callback invocation - std::forward<CallbackFn>(cbfn)() shall - be registered with `t`'s associated stop state as follows: + 3. The callback invocation `std::forward(callback_fn)()` + shall be registered with `t`'s associated stop state as follows: 1. If `t.stop_requested()` evaluates to `false` at the time of registration, the callback invocation is added to the stop state's list of callbacks such that - std::forward<CallbackFn>(cbfn)() is - evaluated if a stop request is made on the stop state. + `std::forward(callback_fn)()` is evaluated if a + stop request is made on the stop state. - 2. Otherwise, - std::forward<CallbackFn>(cbfn)() - shall be immediately evaluated on the thread executing - `scb`'s constructor, and the callback invocation shall not be - added to the list of callback invocations. + 2. Otherwise, `std::forward(callback_fn)()` shall be + immediately evaluated on the thread executing `scb`'s + constructor, and the callback invocation shall not be added + to the list of callback invocations. 4. If the callback invocation was added to stop state's list of callbacks, `scb` shall be associated with the stop state. 2. If `t.stop_possible()` is `false`, there is no requirement that the initialization of `scb` causes the - initialization of `cbfn`. + initialization of `callback_fn`. 3. Destruction of `scb` shall execute a stoppable callback deregistration as follows (in order): 1. If the constructor of `scb` did not register a callback invocation with `t`'s stop state, then the stoppable callback - deregistration shall have no effect other than destroying `cbfn` + deregistration shall have no effect other than destroying `callback_fn` if it was constructed. - 2. Otherwise, the invocation of `cbfn` shall be removed from + 2. Otherwise, the invocation of `callback_fn` shall be removed from the associated stop state. - 3. If `cbfn` is concurrently executing on another thread + 3. If `callback_fn` is concurrently executing on another thread then the stoppable callback deregistration shall block - ([defns.block]) until the invocation of `cbfn` returns - such that the return from the invocation of `cbfn` + ([defns.block]) until the invocation of `callback_fn` returns + such that the return from the invocation of `callback_fn` strongly happens before ([intro.races]) the destruction of - `cbfn`. + `callback_fn`. - 4. If `cbfn` is executing on the current thread, then the + 4. If `callback_fn` is executing on the current thread, then the destructor shall not block waiting for the return from the - invocation of `cbfn`. + invocation of `callback_fn`. 5. A stoppable callback deregistration shall not block on the completion of the invocation of some other callback registered with the same logical stop state. 6. The stoppable callback deregistration shall destroy - `cbfn`. + `callback_fn`. 4. The `stoppable_token` concept checks for the basic interface of a stop token that is copyable and allows polling to see if stop has been requested and @@ -4399,8 +4397,6 @@ Header `` synopsis [thread.stoptoken.syn] and Class 5. If `t` and `u` reference the same stop state, or if both `t` and `u` are disengaged, `t == u` is `true`; otherwise, it is `false`. - - 8. An object whose type models the exposition-only `stoppable-source` concept can be queried whether stop has been requested (`stop_requested`) and whether stop is possible (`stop_possible`). It is a factory for @@ -4420,15 +4416,15 @@ Header `` synopsis [thread.stoptoken.syn] and Class }; - 1. A `stoppable-source` object has at most one associated logical - stop state. A `stoppable-source` object with no associated stop - state is said to be disengaged. For a disengaged - `stoppable-source` object, `stop_possible` and `stop_requested` - shall return `false`. + 1. An object whose type models `stoppable-source` has at most one + associated logical stop state. If it has no associated stop state, it is + said to be disengaged. Let `s` be an object whose type models + `stoppable-source` and that is disengaged. `s.stop_possible()` + and `s.stop_requested()` shall return `false`. - 2. A disengaged `stoppable-source` object shall return a disengaged - stop token from `get_token()`. Otherwise, `get_token()` shall return a - stop token that is associated with the stop state of the source. + 2. Let `t` be an object whose type models `stoppable-source`. If `t` is + disengaged, `t.get_token()` shall return a disengaged stop token; otherwise, + it shall return a stop token that is associated with the stop state of `t`. The following paragraph is moved from the introduction, with minor modifications (underlined in green). @@ -4519,7 +4515,7 @@ namespace std {
1. `stop-state` refers to the `stop_token`'s associated stop state. A - `stop_token` object is disengaged when `stop-state` is null.
+ `stop_token` object is disengaged when `stop-state` is empty. @@ -4582,7 +4578,7 @@ void swap(stop_token& rhs) noexcept; 1. *Effects:* Exchanges the values of `*this` and `rhs`. Equivalent to: - std::swap(stop-state, rhs.stop-state). + stop-state.swap(rhs.stop-state).
 [[nodiscard]] bool stop_requested() const noexcept;
@@ -4634,11 +4630,11 @@ friend void swap(stop_token& x, stop_token& y) noexcept;
 
 #### General [stopsource.general] #### {#spec-stopsource.general}
 
-1. The class `stop_source` implements the semantics of making a stop
+1. The class `stop_source` implements the semantics of making a stop
     request. A stop request made on a `stop_source` object is visible to all
     associated `stop_source` and `stop_token` ([thread.stoptoken]) objects. Once
     a stop request has been made it cannot be withdrawn (a subsequent stop
-    request has no effect)models `stoppable-source`.
+    request has no effect).
 
 
 namespace std {
@@ -4682,9 +4678,10 @@ namespace std {
 
 
1. `stop-state` refers to the `stop_source`'s associated stop state. A - `stop_source` object is disengaged when `stop-state` is null. + `stop_source` object is disengaged when `stop-state` is empty. -2. `stop_source` models `copyable`, `equality_comparable`, and `swappable`. +2. `stop_source` models `stoppable-source`, `copyable`, + `equality_comparable`, and `swappable`.
@@ -4755,29 +4752,29 @@ stop_source& operator=(stop_source&& rhs) noexcept; void swap(stop_source& rhs) noexcept;
-12. *Effects:* Exchanges the values of `*this` and `rhs`Equivalent to: - std::swap(stop-state, rhs.stop-state). +1. *Effects:* Exchanges the values of `*this` and `rhs`Equivalent to: + stop-state.swap(rhs.stop-state).
 [[nodiscard]] stop_token get_token() const noexcept;
 
-1. *Returns:* `stop_token()` if `stop_possible()` is `false`; otherwise a new - associated `stop_token` object; *i.e.*, its `stop-state` pointer - is equal to the `stop-state` pointer of `*this`. +2. *Returns:* `stop_token()` if `stop_possible()` is `false`; otherwise a new + associated `stop_token` object; *i.e.*, its `stop-state` member + is equal to the `stop-state` member of `*this`.
 [[nodiscard]] bool stop_possible() const noexcept;
 
-2. *Returns:* `true` if `*this` has ownership of a stop state; otherwise, +3. *Returns:* `true` if `*this` has ownership of a stop state; otherwise, `false`stop-state != nullptr.
 [[nodiscard]] bool stop_requested() const noexcept;
 
-3. *Returns:* `true` if `*this` has ownership +4. *Returns:* `true` if `*this` has ownership of`stop-state` refers to a stop state that has received a stop request; otherwise, `false`. @@ -4786,7 +4783,7 @@ bool request_stop() noexcept;
-4. *Effects:* Executes a stop request operation ([stoptoken.concepts]) on the +5. *Effects:* Executes a stop request operation ([stoptoken.concepts]) on the associated stop state, if any.
@@ -4847,12 +4844,12 @@ namespace std { using callback_type = CallbackFn; // 33.3.5.2, constructors and destructor - template<class CBF> - explicit stop_callback(const stop_token& st, CBF&& cbfn) - noexcept(is_nothrow_constructible_v<CallbackFn, CBF>); - template<class CBF> - explicit stop_callback(stop_token&& st, CBF&& cbfn) - noexcept(is_nothrow_constructible_v<CallbackFn, CBF>); + template<class CInitializer> + explicit stop_callback(const stop_token& st, CInitializer&& cbinit) + noexcept(is_nothrow_constructible_v<CallbackFn, CInitializer>); + template<class CInitializer> + explicit stop_callback(stop_token&& st, CInitializer&& cbinit) + noexcept(is_nothrow_constructible_v<CallbackFn, CInitializer>); ~stop_callback(); stop_callback(const stop_callback&) = delete; @@ -4882,10 +4879,10 @@ namespace std {
-3. *Remarks:* For a type CBF, if - stoppable-callback-for<CallbackFn, stop_token, CBF> is +3. *Remarks:* For a type Initializer, if + stoppable-callback-for<CallbackFn, stop_token, Initializer> is satisfied, then stoppable-callback-for<CallbackFn, stop_token, - CBF> is modeled. The exposition-only `callback-fn` member is the + Initializer> is modeled. The exposition-only `callback-fn` member is the associated callback function ([stoptoken.concepts]) of `stop_callback` objects. @@ -4894,16 +4891,16 @@ namespace std { #### Constructors and destructor [stopcallback.cons] #### {#spec-stopcallback.cons}
-template<class CBF>
-explicit stop_callback(const stop_token& st, CBF&& cbfn)
-  noexcept(is_nothrow_constructible_v<CallbackFn, CBF>);
-template<class CBF>
-explicit stop_callback(stop_token&& st, CBF&& cbfn)
-  noexcept(is_nothrow_constructible_v<CallbackFn, CBF>);
+template<class CInitializer>
+explicit stop_callback(const stop_token& st, CInitializer&& cbinit)
+  noexcept(is_nothrow_constructible_v<CallbackFn, CInitializer>);
+template<class CInitializer>
+explicit stop_callback(stop_token&& st, CInitializer&& cbinit)
+  noexcept(is_nothrow_constructible_v<CallbackFn, CInitializer>);
 
-1. *Constraints:* CallbackFn and CBF satisfy - constructible_from<CallbackFn, CBF>. +1. *Constraints:* CallbackFn and CInitializer satisfy + constructible_from<CallbackFn, CInitializer>.
2. *Preconditions:* `Callback` and `C` model `constructible_from`. @@ -4912,7 +4909,7 @@ explicit stop_callback(stop_token&& st, CBF&& cbfn) 3. *Effects:* Initializes callbackcallback-fn with - std::forward<CBF>(cbfn) and + std::forward<CInitializer>(cbinit) and executes a stoppable callback registration ([stoptoken.concepts]). If `st.stop_requested()` is `true`, then `std::forward<Callback>(callback)()` is evaluated in the current thread @@ -4944,12 +4941,13 @@ explicit stop_callback(stop_token&& st, CBF&& cbfn) If `callback` is executing on the current thread, then the destructor does not block ([defns.block]) waiting for the return from the invocation of `callback`. Releases Executes a stoppable callback deregistration - ([stoptoken.concepts]), and releases ownership of the stop state, if + ([stoptoken.concepts]) and releases ownership of the stop state, if any. -
+ + Insert a new subclause, Class `never_stop_token` [stoptoken.never], after subclause Class template `stop_callback` @@ -5147,9 +5145,9 @@ added above, as a new subclause of Stop tokens [thread.stoptoken]. using callback_type = CallbackFn; // [stopcallback.inplace.cons], constructors and destructor - template<class CBF> - explicit inplace_stop_callback(inplace_stop_token st, CBF&& cbfn) - noexcept(is_nothrow_constructible_v<CallbackFn, CBF>); + template<class Initializer> + explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init) + noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>); ~inplace_stop_callback(); inplace_stop_callback(inplace_stop_callback&&) = delete; @@ -5171,32 +5169,31 @@ added above, as a new subclause of Stop tokens [thread.stoptoken]. template parameter `CallbackFn` that satisfies both `invocable` and `destructible`. -2. *Remarks:* For a type `CBF`, if +2. *Remarks:* For a type `Initializer`, if stoppable-callback-for<CallbackFn, inplace_stop_token, - CBF> is satisfied, then + Initializer> is satisfied, then stoppable-callback-for<CallbackFn, inplace_stop_token, - CBF> is modeled. The exposition-only `callback-fn` member is - the associated callback function ([stoptoken.concepts]) of + Initializer> is modeled. The exposition-only `callback-fn` + member is the associated callback function ([stoptoken.concepts]) of `inplace_stop_callback` objects. - Implementations are not permitted to use additional storage, such - as dynamic memory, to store the state necessary for an - `inplace_stop_callback`'s association with an `inplace_stop_source` object - or to register the callback invocation with the associated - `inplace_stop_source` object. + Implementations are not permitted to use additional storage, such as dynamic + memory, to store the state necessary for an `inplace_stop_callback`'s + association with an `inplace_stop_source` object or to register the callback + invocation with the associated `inplace_stop_source` object. #### Constructors and destructor [stopcallback.inplace.cons] #### {#spec-stopcallback.inplace.cons}
-template<class CBF>
-  explicit inplace_stop_callback(inplace_stop_token st, CBF&& cbfn)
-    noexcept(is_nothrow_constructible_v<CallbackFn, CBF>);
+template<class Initializer>
+  explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
+    noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
 
-1. *Constraints*: `constructible_from` is satisfied. +1. *Constraints*: `constructible_from` is satisfied. 2. *Effects*: Initializes `callback-fn` with - `std::forward(cbfn)` and executes a stoppable callback registration + `std::forward(init)` and executes a stoppable callback registration ([stoptoken.concepts]).