872 lines
46 KiB
Markdown
872 lines
46 KiB
Markdown
[thread.stoptoken]
|
||
|
||
# 32 Concurrency support library [[thread]](./#thread)
|
||
|
||
## 32.3 Stop tokens [thread.stoptoken]
|
||
|
||
### [32.3.1](#intro) Introduction [[thread.stoptoken.intro]](thread.stoptoken.intro)
|
||
|
||
[1](#intro-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L449)
|
||
|
||
Subclause [thread.stoptoken] describes components that can be used
|
||
to asynchronously request that an operation stops execution in a timely manner,
|
||
typically because the result is no longer required[.](#intro-1.sentence-1)
|
||
|
||
Such a request is called a [*stop request*](#def:stop_request "32.3.1 Introduction [thread.stoptoken.intro]")[.](#intro-1.sentence-2)
|
||
|
||
[2](#intro-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L455)
|
||
|
||
The concepts[*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]"), and[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") specify the required syntax and semantics of
|
||
shared access to a [*stop state*](#def:stop_state "32.3.1 Introduction [thread.stoptoken.intro]")[.](#intro-2.sentence-1)
|
||
|
||
Any object modeling [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]"), or[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") that refers to the same stop state is
|
||
an [*associated*](#def:associated "32.3.1 Introduction [thread.stoptoken.intro]")[*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]"), or[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]"),
|
||
respectively[.](#intro-2.sentence-2)
|
||
|
||
[3](#intro-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L472)
|
||
|
||
An object of a type that models [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") can be passed to an operation that can either
|
||
|
||
- [(3.1)](#intro-3.1)
|
||
|
||
actively poll the token to check if there has been a stop request, or
|
||
|
||
- [(3.2)](#intro-3.2)
|
||
|
||
register a callback that
|
||
will be called in the event that a stop request is made[.](#intro-3.sentence-1)
|
||
|
||
A stop request made via an object
|
||
whose type models [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") will be visible to
|
||
all associated [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") and[*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") objects[.](#intro-3.sentence-2)
|
||
|
||
Once a stop request has been made it cannot be withdrawn
|
||
(a subsequent stop request has no effect)[.](#intro-3.sentence-3)
|
||
|
||
[4](#intro-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L488)
|
||
|
||
Callbacks registered via an object
|
||
whose type models [*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") are called when a stop request is first made
|
||
by any associated [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") object[.](#intro-4.sentence-1)
|
||
|
||
[5](#intro-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L494)
|
||
|
||
The types stop_source and stop_token and
|
||
the class template stop_callback implement
|
||
the semantics of shared ownership of a stop state[.](#intro-5.sentence-1)
|
||
|
||
The last remaining owner of the stop state automatically releases
|
||
the resources associated with the stop state[.](#intro-5.sentence-2)
|
||
|
||
[6](#intro-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L501)
|
||
|
||
An object of type inplace_stop_source is the sole owner of its stop state[.](#intro-6.sentence-1)
|
||
|
||
An object of type inplace_stop_token or
|
||
of a specialization of the class template inplace_stop_callback does not participate in ownership of its associated stop state[.](#intro-6.sentence-2)
|
||
|
||
[*Note [1](#intro-note-1)*:
|
||
|
||
They are for use when all uses of the associated token and callback objects
|
||
are known to nest within the lifetime of the inplace_stop_source object[.](#intro-6.sentence-3)
|
||
|
||
â *end note*]
|
||
|
||
### [32.3.2](#syn) Header <stop_token> synopsis [[thread.stoptoken.syn]](thread.stoptoken.syn)
|
||
|
||
[ð](#header:%3cstop_token%3e)
|
||
|
||
namespace std {// [[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"), stop token conceptstemplate<class CallbackFn, class Token, class Initializer = CallbackFn>concept [*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") = *see below*; // *exposition only*template<class Token>concept [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") = *see below*; template<class Token>concept [unstoppable_token](#concept:unstoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") = *see below*; template<class Source>concept [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") = *see below*; // *exposition only*// [[stoptoken]](#stoptoken "32.3.4 Class stop_token"), class stop_tokenclass stop_token; // [[stopsource]](#stopsource "32.3.5 Class stop_source"), class stop_sourceclass stop_source; // no-shared-stop-state indicatorstruct nostopstate_t {explicit nostopstate_t() = default; }; inline constexpr nostopstate_t nostopstate{}; // [[stopcallback]](#stopcallback "32.3.6 Class template stop_callback"), class template stop_callbacktemplate<class Callback>class stop_callback; // [[stoptoken.never]](#stoptoken.never "32.3.7 Class never_stop_token"), class never_stop_tokenclass never_stop_token; // [[stoptoken.inplace]](#stoptoken.inplace "32.3.8 Class inplace_stop_token"), class inplace_stop_tokenclass inplace_stop_token; // [[stopsource.inplace]](#stopsource.inplace "32.3.9 Class inplace_stop_source"), class inplace_stop_sourceclass inplace_stop_source; // [[stopcallback.inplace]](#stopcallback.inplace "32.3.10 Class template inplace_stop_callback"), class template inplace_stop_callbacktemplate<class CallbackFn>class inplace_stop_callback; template<class T, class CallbackFn>using stop_callback_for_t = T::template callback_type<CallbackFn>;}
|
||
|
||
### [32.3.3](#stoptoken.concepts) Stop token concepts [[stoptoken.concepts]](stoptoken.concepts)
|
||
|
||
[1](#stoptoken.concepts-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L566)
|
||
|
||
The exposition-only [*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") concept
|
||
checks for a callback compatible with a given Token type[.](#stoptoken.concepts-1.sentence-1)
|
||
|
||
template<class CallbackFn, class Token, class Initializer = CallbackFn>concept [*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]") = // *exposition only*[invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]")<CallbackFn> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<CallbackFn, Initializer> &&requires { typename stop_callback_for_t<Token, CallbackFn>; } &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<stop_callback_for_t<Token, CallbackFn>, const Token&, Initializer>;
|
||
|
||
[2](#stoptoken.concepts-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L578)
|
||
|
||
Let t and u be distinct, valid objects of type Token that reference the same logical stop state;
|
||
let init be an expression such that[same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<decltype(init), Initializer> is true; and
|
||
let SCB denote the type stop_callback_for_t<Token, CallbackFn>[.](#stoptoken.concepts-2.sentence-1)
|
||
|
||
[3](#stoptoken.concepts-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L585)
|
||
|
||
The concept[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, Token, Initializer> is modeled only if:
|
||
|
||
- [(3.1)](#stoptoken.concepts-3.1)
|
||
|
||
The following concepts are modeled:
|
||
* [(3.1.1)](#stoptoken.concepts-3.1.1)
|
||
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<SCB, Token, Initializer>
|
||
|
||
* [(3.1.2)](#stoptoken.concepts-3.1.2)
|
||
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<SCB, Token&, Initializer>
|
||
|
||
* [(3.1.3)](#stoptoken.concepts-3.1.3)
|
||
|
||
[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<SCB, const Token, Initializer>
|
||
|
||
- [(3.2)](#stoptoken.concepts-3.2)
|
||
|
||
An object of type SCB has
|
||
an associated callback function of type CallbackFn[.](#stoptoken.concepts-3.2.sentence-1)
|
||
Let scb be an object of type SCB and
|
||
let callback_fn denote scb's associated callback function[.](#stoptoken.concepts-3.2.sentence-2)
|
||
Direct-non-list-initializing scb from
|
||
arguments t and init shall execute a [*stoppable callback registration*](#def:registration,stoppable_callback "32.3.3 Stop token concepts [stoptoken.concepts]") as follows:
|
||
* [(3.2.1)](#stoptoken.concepts-3.2.1)
|
||
|
||
If t.stop_possible() is true:
|
||
+
|
||
[(3.2.1.1)](#stoptoken.concepts-3.2.1.1)
|
||
callback_fn shall be direct-initialized with init[.](#stoptoken.concepts-3.2.1.1.sentence-1)
|
||
|
||
+
|
||
[(3.2.1.2)](#stoptoken.concepts-3.2.1.2)
|
||
Construction of scb shall only throw exceptions
|
||
thrown by the initialization of callback_fn from init[.](#stoptoken.concepts-3.2.1.2.sentence-1)
|
||
|
||
+
|
||
[(3.2.1.3)](#stoptoken.concepts-3.2.1.3)
|
||
The callback invocation std::forward<CallbackFn>(callback_fn)() shall be registered with t's associated stop state as follows:
|
||
- [(3.2.1.3.1)](#stoptoken.concepts-3.2.1.3.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>(
|
||
callback_fn)() is evaluated
|
||
if a stop request is made on the stop state[.](#stoptoken.concepts-3.2.1.3.1.sentence-1)
|
||
|
||
- [(3.2.1.3.2)](#stoptoken.concepts-3.2.1.3.2)
|
||
|
||
Otherwise, std::forward<CallbackFn>(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[.](#stoptoken.concepts-3.2.1.3.2.sentence-1)
|
||
|
||
If the callback invocation was added to stop state's list of callbacks,scb shall be associated with the stop state[.](#stoptoken.concepts-3.2.1.3.sentence-2)
|
||
|
||
* [(3.2.2)](#stoptoken.concepts-3.2.2)
|
||
|
||
[*Note [1](#stoptoken.concepts-note-1)*:
|
||
If t.stop_possible() is false,
|
||
there is no requirement
|
||
that the initialization of scb causes the initialization of callback_fn[.](#stoptoken.concepts-3.2.2.sentence-1)
|
||
â *end note*]
|
||
|
||
- [(3.3)](#stoptoken.concepts-3.3)
|
||
|
||
Destruction of scb shall execute
|
||
a [*stoppable callback deregistration*](#def:callback_deregistration,stoppable "32.3.3 Stop token concepts [stoptoken.concepts]") as follows (in order):
|
||
* [(3.3.1)](#stoptoken.concepts-3.3.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 callback_fn if it was constructed[.](#stoptoken.concepts-3.3.1.sentence-1)
|
||
|
||
* [(3.3.2)](#stoptoken.concepts-3.3.2)
|
||
|
||
Otherwise, the invocation of callback_fn shall be removed
|
||
from the associated stop state[.](#stoptoken.concepts-3.3.2.sentence-1)
|
||
|
||
* [(3.3.3)](#stoptoken.concepts-3.3.3)
|
||
|
||
If callback_fn is concurrently executing on another thread,
|
||
then the stoppable callback deregistration shall block ([[defns.block]](defns.block "3.6 block"))
|
||
until the invocation of callback_fn returns
|
||
such that the return from the invocation of callback_fn strongly happens before ([[intro.races]](intro.races "6.10.2.2 Data races"))
|
||
the destruction of callback_fn[.](#stoptoken.concepts-3.3.3.sentence-1)
|
||
|
||
* [(3.3.4)](#stoptoken.concepts-3.3.4)
|
||
|
||
If callback_fn is executing on the current thread,
|
||
then the destructor shall not block
|
||
waiting for the return from the invocation of callback_fn[.](#stoptoken.concepts-3.3.4.sentence-1)
|
||
|
||
* [(3.3.5)](#stoptoken.concepts-3.3.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[.](#stoptoken.concepts-3.3.5.sentence-1)
|
||
|
||
* [(3.3.6)](#stoptoken.concepts-3.3.6)
|
||
|
||
The stoppable callback deregistration shall destroy callback_fn[.](#stoptoken.concepts-3.3.6.sentence-1)
|
||
|
||
[4](#stoptoken.concepts-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L675)
|
||
|
||
The [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") concept checks
|
||
for the basic interface of a stop token
|
||
that is copyable and allows polling to see if stop has been requested and
|
||
also whether a stop request is possible[.](#stoptoken.concepts-4.sentence-1)
|
||
|
||
The [unstoppable_token](#concept:unstoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") concept checks
|
||
for a [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") type that does not allow stopping[.](#stoptoken.concepts-4.sentence-2)
|
||
|
||
template<template<class> class>struct *check-type-alias-exists*; // *exposition only*template<class Token>concept [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") =requires (const Token tok) {typename *check-type-alias-exists*<Token::template callback_type>; { tok.stop_requested() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { tok.stop_possible() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { Token(tok) } noexcept; // see implicit expression variations ([[concepts.equality]](concepts.equality "18.2 Equality preservation"))} &&[copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]")<Token> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]")<Token>;
|
||
|
||
template<class Token>concept [unstoppable_token](#concept:unstoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") =[stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]")<Token> &&requires (const Token tok) {requires bool_constant<(!tok.stop_possible())>::value; };
|
||
|
||
[5](#stoptoken.concepts-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L705)
|
||
|
||
An object whose type models [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") has at most one associated logical stop state[.](#stoptoken.concepts-5.sentence-1)
|
||
|
||
A [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") object with no associated stop state
|
||
is said to be [*disengaged*](#def:disengaged "32.3.3 Stop token concepts [stoptoken.concepts]")[.](#stoptoken.concepts-5.sentence-2)
|
||
|
||
[6](#stoptoken.concepts-6)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L711)
|
||
|
||
Let SP be an evaluation of t.stop_possible() that is false, and
|
||
let SR be an evaluation of t.stop_requested() that is true[.](#stoptoken.concepts-6.sentence-1)
|
||
|
||
[7](#stoptoken.concepts-7)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L716)
|
||
|
||
The type Token models [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") only if:
|
||
|
||
- [(7.1)](#stoptoken.concepts-7.1)
|
||
|
||
Any evaluation of u.stop_possible() or u.stop_requested() that happens after ([[intro.races]](intro.races "6.10.2.2 Data races")) SP is false[.](#stoptoken.concepts-7.1.sentence-1)
|
||
|
||
- [(7.2)](#stoptoken.concepts-7.2)
|
||
|
||
Any evaluation of u.stop_possible() or u.stop_requested() that happens after SR is true[.](#stoptoken.concepts-7.2.sentence-1)
|
||
|
||
- [(7.3)](#stoptoken.concepts-7.3)
|
||
|
||
For any types CallbackFn and Initializer such that[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, Token, Initializer> is satisfied,[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, Token, Initializer> is modeled[.](#stoptoken.concepts-7.3.sentence-1)
|
||
|
||
- [(7.4)](#stoptoken.concepts-7.4)
|
||
|
||
If t is disengaged,
|
||
evaluations of t.stop_possible() and t.stop_requested() are false[.](#stoptoken.concepts-7.4.sentence-1)
|
||
|
||
- [(7.5)](#stoptoken.concepts-7.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[.](#stoptoken.concepts-7.5.sentence-1)
|
||
|
||
[8](#stoptoken.concepts-8)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L741)
|
||
|
||
An object
|
||
whose type models the exposition-only [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") concept
|
||
can be queried
|
||
whether stop has been requested (stop_requested) and
|
||
whether stop is possible (stop_possible)[.](#stoptoken.concepts-8.sentence-1)
|
||
|
||
It is a factory for associated stop tokens (get_token), and
|
||
a stop request can be made on it (request_stop)[.](#stoptoken.concepts-8.sentence-2)
|
||
|
||
It maintains a list of registered stop callback invocations
|
||
that it executes when a stop request is first made[.](#stoptoken.concepts-8.sentence-3)
|
||
|
||
template<class Source>concept [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") = // *exposition only*requires (Source& src, const Source csrc) { // see implicit expression variations ([[concepts.equality]](concepts.equality "18.2 Equality preservation")){ csrc.get_token() } -> stoppable_token; { csrc.stop_possible() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { csrc.stop_requested() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; { src.request_stop() } -> [same_as](concept.same#concept:same_as "18.4.2 Concept same_as [concept.same]")<bool>; };
|
||
|
||
[9](#stoptoken.concepts-9)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L762)
|
||
|
||
An object whose type models [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") has
|
||
at most one associated logical stop state[.](#stoptoken.concepts-9.sentence-1)
|
||
|
||
If it has no associated stop state, it is said to be disengaged[.](#stoptoken.concepts-9.sentence-2)
|
||
|
||
Let s be an object whose type models [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") and
|
||
that is disengaged[.](#stoptoken.concepts-9.sentence-3)
|
||
|
||
s.stop_possible() and s.stop_requested() shall be false[.](#stoptoken.concepts-9.sentence-4)
|
||
|
||
[10](#stoptoken.concepts-10)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L770)
|
||
|
||
Let t be an object whose type models [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]")[.](#stoptoken.concepts-10.sentence-1)
|
||
|
||
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[.](#stoptoken.concepts-10.sentence-2)
|
||
|
||
[11](#stoptoken.concepts-11)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L777)
|
||
|
||
Calls to the member functionsrequest_stop, stop_requested, and stop_possible and
|
||
similarly named member functions
|
||
on associated [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") objects
|
||
do not introduce data races[.](#stoptoken.concepts-11.sentence-1)
|
||
|
||
A call to request_stop that returns true synchronizes with
|
||
a call to stop_requested on
|
||
an associated[stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") or [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") object
|
||
that returns true[.](#stoptoken.concepts-11.sentence-2)
|
||
|
||
Registration of a callback synchronizes with the invocation of that callback[.](#stoptoken.concepts-11.sentence-3)
|
||
|
||
[12](#stoptoken.concepts-12)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L790)
|
||
|
||
If the [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]") is disengaged,request_stop shall have no effect and return false[.](#stoptoken.concepts-12.sentence-1)
|
||
|
||
Otherwise, it shall execute a [*stop request operation*](#def:operation,stop_request "32.3.3 Stop token concepts [stoptoken.concepts]") on the associated stop state[.](#stoptoken.concepts-12.sentence-2)
|
||
|
||
A stop request operation determines
|
||
whether the stop state has received a stop request, and
|
||
if not, makes a stop request[.](#stoptoken.concepts-12.sentence-3)
|
||
|
||
The determination and making of the stop request shall happen atomically,
|
||
as-if by a read-modify-write operation ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#stoptoken.concepts-12.sentence-4)
|
||
|
||
If the request was made,
|
||
the stop state's registered callback invocations shall be
|
||
synchronously executed[.](#stoptoken.concepts-12.sentence-5)
|
||
|
||
If an invocation of a callback exits via an exception
|
||
then terminate shall be invoked ([[except.terminate]](except.terminate "14.6.2 The std::terminate function"))[.](#stoptoken.concepts-12.sentence-6)
|
||
|
||
[*Note [2](#stoptoken.concepts-note-2)*:
|
||
|
||
No constraint is placed on the order
|
||
in which the callback invocations are executed[.](#stoptoken.concepts-12.sentence-7)
|
||
|
||
â *end note*]
|
||
|
||
request_stop shall return true if a stop request was made, andfalse otherwise[.](#stoptoken.concepts-12.sentence-8)
|
||
|
||
After a call to request_stop either
|
||
a call to stop_possible shall return false or
|
||
a call to stop_requested shall return true[.](#stoptoken.concepts-12.sentence-9)
|
||
|
||
[*Note [3](#stoptoken.concepts-note-3)*:
|
||
|
||
A stop request includes notifying
|
||
all condition variables of type condition_variable_any temporarily registered during
|
||
an interruptible wait ([[thread.condvarany.intwait]](thread.condvarany.intwait "32.7.5.3 Interruptible waits"))[.](#stoptoken.concepts-12.sentence-10)
|
||
|
||
â *end note*]
|
||
|
||
### [32.3.4](#stoptoken) Class stop_token [[stoptoken]](stoptoken)
|
||
|
||
#### [32.3.4.1](#stoptoken.general) General [[stoptoken.general]](stoptoken.general)
|
||
|
||
[1](#stoptoken.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L826)
|
||
|
||
The class stop_token models the concept [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]")[.](#stoptoken.general-1.sentence-1)
|
||
|
||
It shares ownership of its stop state, if any,
|
||
with its associated stop_source object ([[stopsource]](#stopsource "32.3.5 Class stop_source")) and
|
||
any stop_token objects to which it compares equal[.](#stoptoken.general-1.sentence-2)
|
||
|
||
namespace std {class stop_token {public:template<class CallbackFn>using callback_type = stop_callback<CallbackFn>;
|
||
|
||
stop_token() noexcept = default; // [[stoptoken.mem]](#stoptoken.mem "32.3.4.2 Member functions"), member functionsvoid swap(stop_token&) noexcept; bool stop_requested() const noexcept; bool stop_possible() const noexcept; bool operator==(const stop_token& rhs) noexcept = default; private: shared_ptr<*unspecified*> *stop-state*; // *exposition only*};}
|
||
|
||
[2](#stoptoken.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L856)
|
||
|
||
*stop-state* refers to the stop_token's associated stop state[.](#stoptoken.general-2.sentence-1)
|
||
|
||
A stop_token object is disengaged when *stop-state* is empty[.](#stoptoken.general-2.sentence-2)
|
||
|
||
#### [32.3.4.2](#stoptoken.mem) Member functions [[stoptoken.mem]](stoptoken.mem)
|
||
|
||
[ð](#lib:swap,stop_token)
|
||
|
||
`void swap(stop_token& rhs) noexcept;
|
||
`
|
||
|
||
[1](#stoptoken.mem-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L868)
|
||
|
||
*Effects*: Equivalent to:*stop-state*.swap(rhs.*stop-state*);
|
||
|
||
[ð](#lib:stop_requested,stop_token)
|
||
|
||
`bool stop_requested() const noexcept;
|
||
`
|
||
|
||
[2](#stoptoken.mem-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L882)
|
||
|
||
*Returns*: true if *stop-state* refers to a stop state
|
||
that has received a stop request;
|
||
otherwise, false[.](#stoptoken.mem-2.sentence-1)
|
||
|
||
[ð](#lib:stop_possible,stop_token)
|
||
|
||
`bool stop_possible() const noexcept;
|
||
`
|
||
|
||
[3](#stoptoken.mem-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L895)
|
||
|
||
*Returns*: false if
|
||
|
||
- [(3.1)](#stoptoken.mem-3.1)
|
||
|
||
*this is disengaged, or
|
||
|
||
- [(3.2)](#stoptoken.mem-3.2)
|
||
|
||
a stop request was not made
|
||
and there are no associated stop_source objects;
|
||
|
||
otherwise, true[.](#stoptoken.mem-3.sentence-1)
|
||
|
||
### [32.3.5](#stopsource) Class stop_source [[stopsource]](stopsource)
|
||
|
||
#### [32.3.5.1](#stopsource.general) General [[stopsource.general]](stopsource.general)
|
||
|
||
namespace std {class stop_source {public:// [[stopsource.cons]](#stopsource.cons "32.3.5.2 Constructors, copy, and assignment"), constructors, copy, and assignment stop_source(); explicit stop_source(nostopstate_t) noexcept {}// [[stopsource.mem]](#stopsource.mem "32.3.5.3 Member functions"), member functionsvoid swap(stop_source&) noexcept;
|
||
|
||
stop_token get_token() const noexcept; bool stop_possible() const noexcept; bool stop_requested() const noexcept; bool request_stop() noexcept; bool operator==(const stop_source& rhs) noexcept = default; private: shared_ptr<*unspecified*> *stop-state*; // *exposition only*};}
|
||
|
||
[1](#stopsource.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L935)
|
||
|
||
*stop-state* refers to the stop_source's associated stop state[.](#stopsource.general-1.sentence-1)
|
||
|
||
A stop_source object is disengaged when *stop-state* is empty[.](#stopsource.general-1.sentence-2)
|
||
|
||
[2](#stopsource.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L939)
|
||
|
||
stop_source models[*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]"),[copyable](concepts.object#concept:copyable "18.6 Object concepts [concepts.object]"),[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4 Concept equality_comparable [concept.equalitycomparable]"), and[swappable](concept.swappable#concept:swappable "18.4.9 Concept swappable [concept.swappable]")[.](#stopsource.general-2.sentence-1)
|
||
|
||
#### [32.3.5.2](#stopsource.cons) Constructors, copy, and assignment [[stopsource.cons]](stopsource.cons)
|
||
|
||
[ð](#lib:stop_source,constructor)
|
||
|
||
`stop_source();
|
||
`
|
||
|
||
[1](#stopsource.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L954)
|
||
|
||
*Effects*: Initializes *stop-state* with a pointer to a new stop state[.](#stopsource.cons-1.sentence-1)
|
||
|
||
[2](#stopsource.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L958)
|
||
|
||
*Postconditions*: stop_possible() is true and stop_requested() is false[.](#stopsource.cons-2.sentence-1)
|
||
|
||
[3](#stopsource.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L963)
|
||
|
||
*Throws*: bad_alloc if memory cannot be allocated for the stop state[.](#stopsource.cons-3.sentence-1)
|
||
|
||
#### [32.3.5.3](#stopsource.mem) Member functions [[stopsource.mem]](stopsource.mem)
|
||
|
||
[ð](#lib:swap,stop_source)
|
||
|
||
`void swap(stop_source& rhs) noexcept;
|
||
`
|
||
|
||
[1](#stopsource.mem-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L976)
|
||
|
||
*Effects*: Equivalent to:*stop-state*.swap(rhs.*stop-state*);
|
||
|
||
[ð](#lib:get_token,stop_source)
|
||
|
||
`stop_token get_token() const noexcept;
|
||
`
|
||
|
||
[2](#stopsource.mem-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L990)
|
||
|
||
*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[.](#stopsource.mem-2.sentence-1)
|
||
|
||
[ð](#lib:stop_possible,stop_source)
|
||
|
||
`bool stop_possible() const noexcept;
|
||
`
|
||
|
||
[3](#stopsource.mem-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1004)
|
||
|
||
*Returns*: *stop-state* != nullptr[.](#stopsource.mem-3.sentence-1)
|
||
|
||
[ð](#lib:stop_requested,stop_source)
|
||
|
||
`bool stop_requested() const noexcept;
|
||
`
|
||
|
||
[4](#stopsource.mem-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1015)
|
||
|
||
*Returns*: true if *stop-state* refers to a stop state
|
||
that has received a stop request;
|
||
otherwise, false[.](#stopsource.mem-4.sentence-1)
|
||
|
||
[ð](#lib:request_stop,stop_source)
|
||
|
||
`bool request_stop() noexcept;
|
||
`
|
||
|
||
[5](#stopsource.mem-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1028)
|
||
|
||
*Effects*: Executes a stop request operation ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts")) on
|
||
the associated stop state, if any[.](#stopsource.mem-5.sentence-1)
|
||
|
||
### [32.3.6](#stopcallback) Class template stop_callback [[stopcallback]](stopcallback)
|
||
|
||
#### [32.3.6.1](#stopcallback.general) General [[stopcallback.general]](stopcallback.general)
|
||
|
||
[1](#stopcallback.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1039)
|
||
|
||
[ð](#lib:stop_callback_)
|
||
|
||
namespace std {template<class CallbackFn>class stop_callback {public:using callback_type = CallbackFn; // [[stopcallback.cons]](#stopcallback.cons "32.3.6.2 Constructors and destructor"), constructors and destructortemplate<class Initializer>explicit stop_callback(const stop_token& st, Initializer&& init)noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>); template<class Initializer>explicit stop_callback(stop_token&& st, Initializer&& init)noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>); ~stop_callback();
|
||
|
||
stop_callback(const stop_callback&) = delete;
|
||
stop_callback(stop_callback&&) = delete;
|
||
stop_callback& operator=(const stop_callback&) = delete;
|
||
stop_callback& operator=(stop_callback&&) = delete; private: CallbackFn *callback-fn*; // *exposition only*}; template<class CallbackFn> stop_callback(stop_token, CallbackFn) -> stop_callback<CallbackFn>;}
|
||
|
||
[2](#stopcallback.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1071)
|
||
|
||
*Mandates*: stop_callback is instantiated with an argument for the
|
||
template parameter CallbackFn that satisfies both [invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]") and [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")[.](#stopcallback.general-2.sentence-1)
|
||
|
||
[3](#stopcallback.general-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1078)
|
||
|
||
*Remarks*: For a type Initializer,
|
||
if[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, stop_token, Initializer> is satisfied, then[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, stop_token, Initializer> is modeled[.](#stopcallback.general-3.sentence-1)
|
||
|
||
The exposition-only *callback-fn* member is
|
||
the associated callback function ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts")) ofstop_callback<
|
||
CallbackFn> objects[.](#stopcallback.general-3.sentence-2)
|
||
|
||
#### [32.3.6.2](#stopcallback.cons) Constructors and destructor [[stopcallback.cons]](stopcallback.cons)
|
||
|
||
[ð](#lib:stop_callback,constructor)
|
||
|
||
`template<class Initializer>
|
||
explicit stop_callback(const stop_token& st, Initializer&& init)
|
||
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
|
||
|
||
template<class Initializer>
|
||
explicit stop_callback(stop_token&& st, Initializer&& init)
|
||
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
|
||
`
|
||
|
||
[1](#stopcallback.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1103)
|
||
|
||
*Constraints*: CallbackFn and Initializer satisfy[constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<CallbackFn, Initializer>[.](#stopcallback.cons-1.sentence-1)
|
||
|
||
[2](#stopcallback.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1108)
|
||
|
||
*Effects*: Initializes *callback-fn* with std::forward<Initializer>(init) and executes a stoppable callback registration ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"))[.](#stopcallback.cons-2.sentence-1)
|
||
|
||
If a callback is registered with st's shared stop state,
|
||
then *this acquires shared ownership of that stop state[.](#stopcallback.cons-2.sentence-2)
|
||
|
||
[ð](#lib:stop_callback,destructor)
|
||
|
||
`~stop_callback();
|
||
`
|
||
|
||
[3](#stopcallback.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1122)
|
||
|
||
*Effects*: Executes a stoppable callback deregistration ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts")) and
|
||
releases ownership of the stop state, if any[.](#stopcallback.cons-3.sentence-1)
|
||
|
||
### [32.3.7](#stoptoken.never) Class never_stop_token [[stoptoken.never]](stoptoken.never)
|
||
|
||
[1](#stoptoken.never-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1130)
|
||
|
||
The class never_stop_token models
|
||
the [unstoppable_token](#concept:unstoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]") concept[.](#stoptoken.never-1.sentence-1)
|
||
|
||
It provides a stop token interface,
|
||
but also provides static information
|
||
that a stop is never possible nor requested[.](#stoptoken.never-1.sentence-2)
|
||
|
||
namespace std {class never_stop_token {struct *callback-type* { // *exposition only*explicit *callback-type*(never_stop_token, auto&&) noexcept {}}; public:template<class>using callback_type = *callback-type*; static constexpr bool stop_requested() noexcept { return false; }static constexpr bool stop_possible() noexcept { return false; }bool operator==(const never_stop_token&) const = default; };}
|
||
|
||
### [32.3.8](#stoptoken.inplace) Class inplace_stop_token [[stoptoken.inplace]](stoptoken.inplace)
|
||
|
||
#### [32.3.8.1](#stoptoken.inplace.general) General [[stoptoken.inplace.general]](stoptoken.inplace.general)
|
||
|
||
[1](#stoptoken.inplace.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1158)
|
||
|
||
The class inplace_stop_token models
|
||
the concept [stoppable_token](#concept:stoppable_token "32.3.3 Stop token concepts [stoptoken.concepts]")[.](#stoptoken.inplace.general-1.sentence-1)
|
||
|
||
It references the stop state of
|
||
its associated inplace_stop_source object ([[stopsource.inplace]](#stopsource.inplace "32.3.9 Class inplace_stop_source")),
|
||
if any[.](#stoptoken.inplace.general-1.sentence-2)
|
||
|
||
namespace std {class inplace_stop_token {public:template<class CallbackFn>using callback_type = inplace_stop_callback<CallbackFn>;
|
||
|
||
inplace_stop_token() = default; bool operator==(const inplace_stop_token&) const = default; // [[stoptoken.inplace.mem]](#stoptoken.inplace.mem "32.3.8.2 Member functions"), member functionsbool stop_requested() const noexcept; bool stop_possible() const noexcept; void swap(inplace_stop_token&) noexcept; private:const inplace_stop_source* *stop-source* = nullptr; // *exposition only*};}
|
||
|
||
#### [32.3.8.2](#stoptoken.inplace.mem) Member functions [[stoptoken.inplace.mem]](stoptoken.inplace.mem)
|
||
|
||
[ð](#stoptoken.inplace.mem-itemdecl:1)
|
||
|
||
`void swap(inplace_stop_token& rhs) noexcept;
|
||
`
|
||
|
||
[1](#stoptoken.inplace.mem-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1192)
|
||
|
||
*Effects*: Exchanges the values of *stop-source* and rhs.*stop-source*[.](#stoptoken.inplace.mem-1.sentence-1)
|
||
|
||
[ð](#stoptoken.inplace.mem-itemdecl:2)
|
||
|
||
`bool stop_requested() const noexcept;
|
||
`
|
||
|
||
[2](#stoptoken.inplace.mem-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1202)
|
||
|
||
*Effects*: Equivalent to:return *stop-source* != nullptr && *stop-source*->stop_requested();
|
||
|
||
[3](#stoptoken.inplace.mem-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1209)
|
||
|
||
[*Note [1](#stoptoken.inplace.mem-note-1)*:
|
||
|
||
As specified in [[basic.life]](basic.life "6.8.4 Lifetime"),
|
||
the behavior of stop_requested is undefined
|
||
unless the call strongly happens before the start of
|
||
the destructor of the associated inplace_stop_source object, if any[.](#stoptoken.inplace.mem-3.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
[ð](#stoptoken.inplace.mem-itemdecl:3)
|
||
|
||
`stop_possible() const noexcept;
|
||
`
|
||
|
||
[4](#stoptoken.inplace.mem-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1223)
|
||
|
||
*Returns*: *stop-source* != nullptr[.](#stoptoken.inplace.mem-4.sentence-1)
|
||
|
||
[5](#stoptoken.inplace.mem-5)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1227)
|
||
|
||
[*Note [2](#stoptoken.inplace.mem-note-2)*:
|
||
|
||
As specified in [[basic.stc.general]](basic.stc.general "6.8.6.1 General"),
|
||
the behavior of stop_possible is implementation-defined
|
||
unless the call strongly happens before
|
||
the end of the storage duration of
|
||
the associated inplace_stop_source object, if any[.](#stoptoken.inplace.mem-5.sentence-1)
|
||
|
||
â *end note*]
|
||
|
||
### [32.3.9](#stopsource.inplace) Class inplace_stop_source [[stopsource.inplace]](stopsource.inplace)
|
||
|
||
#### [32.3.9.1](#stopsource.inplace.general) General [[stopsource.inplace.general]](stopsource.inplace.general)
|
||
|
||
[1](#stopsource.inplace.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1241)
|
||
|
||
The class inplace_stop_source models [*stoppable-source*](#concept:stoppable-source "32.3.3 Stop token concepts [stoptoken.concepts]")[.](#stopsource.inplace.general-1.sentence-1)
|
||
|
||
namespace std {class inplace_stop_source {public:// [[stopsource.inplace.cons]](#stopsource.inplace.cons "32.3.9.2 Constructors"), constructorsconstexpr inplace_stop_source() noexcept;
|
||
|
||
inplace_stop_source(inplace_stop_source&&) = delete;
|
||
inplace_stop_source(const inplace_stop_source&) = delete;
|
||
inplace_stop_source& operator=(inplace_stop_source&&) = delete;
|
||
inplace_stop_source& operator=(const inplace_stop_source&) = delete; ~inplace_stop_source(); // [[stopsource.inplace.mem]](#stopsource.inplace.mem "32.3.9.3 Member functions"), stop handlingconstexpr inplace_stop_token get_token() const noexcept; static constexpr bool stop_possible() noexcept { return true; }bool stop_requested() const noexcept; bool request_stop() noexcept; };}
|
||
|
||
#### [32.3.9.2](#stopsource.inplace.cons) Constructors [[stopsource.inplace.cons]](stopsource.inplace.cons)
|
||
|
||
[ð](#stopsource.inplace.cons-itemdecl:1)
|
||
|
||
`constexpr inplace_stop_source() noexcept;
|
||
`
|
||
|
||
[1](#stopsource.inplace.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1273)
|
||
|
||
*Effects*: Initializes a new stop state inside *this[.](#stopsource.inplace.cons-1.sentence-1)
|
||
|
||
[2](#stopsource.inplace.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1277)
|
||
|
||
*Postconditions*: stop_requested() is false[.](#stopsource.inplace.cons-2.sentence-1)
|
||
|
||
#### [32.3.9.3](#stopsource.inplace.mem) Member functions [[stopsource.inplace.mem]](stopsource.inplace.mem)
|
||
|
||
[ð](#stopsource.inplace.mem-itemdecl:1)
|
||
|
||
`constexpr inplace_stop_token get_token() const noexcept;
|
||
`
|
||
|
||
[1](#stopsource.inplace.mem-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1289)
|
||
|
||
*Returns*: A new associated inplace_stop_token object
|
||
whose *stop-source* member is equal to this[.](#stopsource.inplace.mem-1.sentence-1)
|
||
|
||
[ð](#stopsource.inplace.mem-itemdecl:2)
|
||
|
||
`bool stop_requested() const noexcept;
|
||
`
|
||
|
||
[2](#stopsource.inplace.mem-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1300)
|
||
|
||
*Returns*: true if the stop state inside *this has received a stop request; otherwise, false[.](#stopsource.inplace.mem-2.sentence-1)
|
||
|
||
[ð](#stopsource.inplace.mem-itemdecl:3)
|
||
|
||
`bool request_stop() noexcept;
|
||
`
|
||
|
||
[3](#stopsource.inplace.mem-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1311)
|
||
|
||
*Effects*: Executes a stop request operation ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"))[.](#stopsource.inplace.mem-3.sentence-1)
|
||
|
||
[4](#stopsource.inplace.mem-4)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1315)
|
||
|
||
*Postconditions*: stop_requested() is true[.](#stopsource.inplace.mem-4.sentence-1)
|
||
|
||
### [32.3.10](#stopcallback.inplace) Class template inplace_stop_callback [[stopcallback.inplace]](stopcallback.inplace)
|
||
|
||
#### [32.3.10.1](#stopcallback.inplace.general) General [[stopcallback.inplace.general]](stopcallback.inplace.general)
|
||
|
||
namespace std {template<class CallbackFn>class inplace_stop_callback {public:using callback_type = CallbackFn; // [[stopcallback.inplace.cons]](#stopcallback.inplace.cons "32.3.10.2 Constructors and destructor"), constructors and destructortemplate<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;
|
||
inplace_stop_callback(const inplace_stop_callback&) = delete;
|
||
inplace_stop_callback& operator=(inplace_stop_callback&&) = delete;
|
||
inplace_stop_callback& operator=(const inplace_stop_callback&) = delete; private: CallbackFn *callback-fn*; // *exposition only*}; template<class CallbackFn> inplace_stop_callback(inplace_stop_token, CallbackFn)-> inplace_stop_callback<CallbackFn>;}
|
||
|
||
[1](#stopcallback.inplace.general-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1352)
|
||
|
||
*Mandates*: CallbackFn satisfies both[invocable](concept.invocable#concept:invocable "18.7.2 Concept invocable [concept.invocable]") and [destructible](concept.destructible#concept:destructible "18.4.10 Concept destructible [concept.destructible]")[.](#stopcallback.inplace.general-1.sentence-1)
|
||
|
||
[2](#stopcallback.inplace.general-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1357)
|
||
|
||
*Remarks*: For a type Initializer, if[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, inplace_stop_token, Initializer> is satisfied, then[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3 Stop token concepts [stoptoken.concepts]")<CallbackFn, inplace_stop_token, Initializer> is modeled[.](#stopcallback.inplace.general-2.sentence-1)
|
||
|
||
For an inplace_stop_callback<CallbackFn> object,
|
||
the exposition-only *callback-fn* member is
|
||
its associated callback function ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"))[.](#stopcallback.inplace.general-2.sentence-2)
|
||
|
||
#### [32.3.10.2](#stopcallback.inplace.cons) Constructors and destructor [[stopcallback.inplace.cons]](stopcallback.inplace.cons)
|
||
|
||
[ð](#stopcallback.inplace.cons-itemdecl:1)
|
||
|
||
`template<class Initializer>
|
||
explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
|
||
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
|
||
`
|
||
|
||
[1](#stopcallback.inplace.cons-1)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1381)
|
||
|
||
*Constraints*: [constructible_from](concept.constructible#concept:constructible_from "18.4.11 Concept constructible_from [concept.constructible]")<CallbackFn, Initializer> is satisfied[.](#stopcallback.inplace.cons-1.sentence-1)
|
||
|
||
[2](#stopcallback.inplace.cons-2)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1385)
|
||
|
||
*Effects*: Initializes *callback-fn* with std::forward<Initializer>(init) and executes a stoppable callback registration ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"))[.](#stopcallback.inplace.cons-2.sentence-1)
|
||
|
||
[ð](#stopcallback.inplace.cons-itemdecl:2)
|
||
|
||
`~inplace_stop_callback();
|
||
`
|
||
|
||
[3](#stopcallback.inplace.cons-3)
|
||
|
||
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L1396)
|
||
|
||
*Effects*: Executes a stoppable callback deregistration ([[stoptoken.concepts]](#stoptoken.concepts "32.3.3 Stop token concepts"))[.](#stopcallback.inplace.cons-3.sentence-1)
|