Files
2025-10-25 03:02:53 +03:00

872 lines
46 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.1Introduction[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.3Stop token concepts[stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3Stop token concepts[stoptoken.concepts]"), and[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop token concepts[stoptoken.concepts]") specify the required syntax and semantics of
shared access to a [*stop state*](#def:stop_state "32.3.1Introduction[thread.stoptoken.intro]")[.](#intro-2.sentence-1)
Any object modeling [*stoppable-source*](#concept:stoppable-source "32.3.3Stop token concepts[stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3Stop token concepts[stoptoken.concepts]"), or[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop token concepts[stoptoken.concepts]") that refers to the same stop state is
an [*associated*](#def:associated "32.3.1Introduction[thread.stoptoken.intro]")[*stoppable-source*](#concept:stoppable-source "32.3.3Stop token concepts[stoptoken.concepts]"),[stoppable_token](#concept:stoppable_token "32.3.3Stop token concepts[stoptoken.concepts]"), or[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") will be visible to
all associated [stoppable_token](#concept:stoppable_token "32.3.3Stop token concepts[stoptoken.concepts]") and[*stoppable-source*](#concept:stoppable-source "32.3.3Stop 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.3Stop token concepts[stoptoken.concepts]") are called when a stop request is first made
by any associated [*stoppable-source*](#concept:stoppable-source "32.3.3Stop 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.3Stop token concepts"), stop token conceptstemplate<class CallbackFn, class Token, class Initializer = CallbackFn>concept [*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop token concepts[stoptoken.concepts]") = *see below*; // *exposition only*template<class Token>concept [stoppable_token](#concept:stoppable_token "32.3.3Stop token concepts[stoptoken.concepts]") = *see below*; template<class Token>concept [unstoppable_token](#concept:unstoppable_token "32.3.3Stop token concepts[stoptoken.concepts]") = *see below*; template<class Source>concept [*stoppable-source*](#concept:stoppable-source "32.3.3Stop token concepts[stoptoken.concepts]") = *see below*; // *exposition only*// [[stoptoken]](#stoptoken "32.3.4Class stop_­token"), class stop_tokenclass stop_token; // [[stopsource]](#stopsource "32.3.5Class 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.6Class template stop_­callback"), class template stop_callbacktemplate<class Callback>class stop_callback; // [[stoptoken.never]](#stoptoken.never "32.3.7Class never_­stop_­token"), class never_stop_tokenclass never_stop_token; // [[stoptoken.inplace]](#stoptoken.inplace "32.3.8Class inplace_­stop_­token"), class inplace_stop_tokenclass inplace_stop_token; // [[stopsource.inplace]](#stopsource.inplace "32.3.9Class inplace_­stop_­source"), class inplace_stop_sourceclass inplace_stop_source; // [[stopcallback.inplace]](#stopcallback.inplace "32.3.10Class 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") = // *exposition only*[invocable](concept.invocable#concept:invocable "18.7.2Concept invocable[concept.invocable]")<CallbackFn> &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<CallbackFn, Initializer> &&requires { typename stop_callback_for_t<Token, CallbackFn>; } &&[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.2Concept 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.3Stop 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.11Concept constructible_­from[concept.constructible]")<SCB, Token, Initializer>
* [(3.1.2)](#stoptoken.concepts-3.1.2)
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept constructible_­from[concept.constructible]")<SCB, Token&, Initializer>
* [(3.1.3)](#stoptoken.concepts-3.1.3)
[constructible_from](concept.constructible#concept:constructible_from "18.4.11Concept 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.3Stop 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.3Stop 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.6block"))
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.2Data 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") concept checks
for a [stoppable_token](#concept:stoppable_token "32.3.3Stop 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.3Stop 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.2Concept same_­as[concept.same]")<bool>; { tok.stop_possible() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<bool>; { Token(tok) } noexcept; // see implicit expression variations ([[concepts.equality]](concepts.equality "18.2Equality preservation"))} &&[copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]")<Token> &&[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<Token>;
template<class Token>concept [unstoppable_token](#concept:unstoppable_token "32.3.3Stop token concepts[stoptoken.concepts]") =[stoppable_token](#concept:stoppable_token "32.3.3Stop 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") object with no associated stop state
is said to be [*disengaged*](#def:disengaged "32.3.3Stop 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.3Stop 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.2Data 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.3Stop token concepts[stoptoken.concepts]")<CallbackFn, Token, Initializer> is satisfied,[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") = // *exposition only*requires (Source& src, const Source csrc) { // see implicit expression variations ([[concepts.equality]](concepts.equality "18.2Equality preservation")){ csrc.get_token() } -> stoppable_token; { csrc.stop_possible() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<bool>; { csrc.stop_requested() } noexcept -> [same_as](concept.same#concept:same_as "18.4.2Concept same_­as[concept.same]")<bool>; { src.request_stop() } -> [same_as](concept.same#concept:same_as "18.4.2Concept 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.3Stop 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.3Stop 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.3Stop 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.3Stop 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.3Stop token concepts[stoptoken.concepts]") or [*stoppable-source*](#concept:stoppable-source "32.3.3Stop 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.3Stop 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.3Stop 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.2Data 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.2The 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.3Interruptible 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.3Stop 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.5Class 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.2Member 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.2Constructors, copy, and assignment"), constructors, copy, and assignment stop_source(); explicit stop_source(nostopstate_t) noexcept {}// [[stopsource.mem]](#stopsource.mem "32.3.5.3Member 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.3Stop token concepts[stoptoken.concepts]"),[copyable](concepts.object#concept:copyable "18.6Object concepts[concepts.object]"),[equality_comparable](concept.equalitycomparable#concept:equality_comparable "18.5.4Concept equality_­comparable[concept.equalitycomparable]"), and[swappable](concept.swappable#concept:swappable "18.4.9Concept 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.3Stop 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.2Constructors 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.2Concept invocable[concept.invocable]") and [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.3Stop token concepts[stoptoken.concepts]")<CallbackFn, stop_token, Initializer> is satisfied, then[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop 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.3Stop 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.11Concept 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.3Stop 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.3Stop 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.3Stop 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.3Stop 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.9Class 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.2Member 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.4Lifetime"),
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.1General"),
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.3Stop 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.2Constructors"), 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.3Member 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.3Stop 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.2Constructors 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.2Concept invocable[concept.invocable]") and [destructible](concept.destructible#concept:destructible "18.4.10Concept 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.3Stop token concepts[stoptoken.concepts]")<CallbackFn, inplace_stop_token, Initializer> is satisfied, then[*stoppable-callback-for*](#concept:stoppable-callback-for "32.3.3Stop 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.3Stop 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.11Concept 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.3Stop 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.3Stop token concepts"))[.](#stopcallback.inplace.cons-3.sentence-1)