If the
stoppable-source is disengaged,
request_stop shall have no effect and return
false. A stop request operation determines
whether the stop state has received a stop request, and
if not, makes a stop request
. The determination and making of the stop request shall happen atomically,
as-if by a read-modify-write operation (
[intro.races])
. If the request was made,
the stop state's registered callback invocations shall be
synchronously executed
. If an invocation of a callback exits via an exception
then
terminate shall be invoked (
[except.terminate])
. [
Note 2:
No constraint is placed on the order
in which the callback invocations are executed
. —
end note]
request_stop shall return
true if a stop request was made, and
false otherwise
. After a call to
request_stop either
a call to
stop_possible shall return
false or
a call to
stop_requested shall return
true. [
Note 3:
A stop request includes notifying
all condition variables of type
condition_variable_any
temporarily registered during
an interruptible wait (
[thread.condvarany.intwait])
. —
end note]
It shares ownership of its stop state, if any,
with its associated
stop_source object (
[stopsource]) and
any
stop_token objects to which it compares equal
. namespace std {
class stop_token {
public:
template<class CallbackFn>
using callback_type = stop_callback<CallbackFn>;
stop_token() noexcept = default;
void 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;
};
}
stop-state refers to the
stop_token's associated stop state
. A
stop_token object is disengaged when
stop-state is empty
.void swap(stop_token& rhs) noexcept;
Effects: Equivalent to:
stop-state.swap(rhs.stop-state);
bool stop_requested() const noexcept;
Returns:
true if
stop-state refers to a stop state
that has received a stop request;
otherwise,
false. bool stop_possible() const noexcept;
Returns:
false if
- *this is disengaged, or
- a stop request was not made
and there are no associated stop_source objects;
otherwise,
true. namespace std {
class stop_source {
public:
stop_source();
explicit stop_source(nostopstate_t) noexcept {}
void 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;
};
}
Postconditions:
stop_possible() is
true
and
stop_requested() is
false. Throws:
bad_alloc if memory cannot be allocated for the stop state
. void swap(stop_source& rhs) noexcept;
Effects: Equivalent to:
stop-state.swap(rhs.stop-state);
stop_token get_token() const noexcept;
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. bool stop_possible() const noexcept;
Returns:
stop-state != nullptr. bool stop_requested() const noexcept;
Returns:
true if
stop-state refers to a stop state
that has received a stop request;
otherwise,
false. bool request_stop() noexcept;
namespace std {
template<class CallbackFn>
class stop_callback {
public:
using callback_type = CallbackFn;
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>);
~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;
};
template<class CallbackFn>
stop_callback(stop_token, CallbackFn) -> stop_callback<CallbackFn>;
}
Mandates:
stop_callback is instantiated with an argument for the
template parameter
CallbackFn
that satisfies both
invocable
and
destructible. The exposition-only
callback-fn member is
the associated callback function (
[stoptoken.concepts]) of
stop_callback<
CallbackFn> objects
. 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>);
Effects: Initializes
callback-fn with
std::forward<Initializer>(init)
and executes a stoppable callback registration (
[stoptoken.concepts])
. If a callback is registered with
st's shared stop state,
then
*this acquires shared ownership of that stop state
.Effects: Executes a stoppable callback deregistration (
[stoptoken.concepts]) and
releases ownership of the stop state, if any
. It provides a stop token interface,
but also provides static information
that a stop is never possible nor requested
. namespace std {
class never_stop_token {
struct callback-type {
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;
};
}
It references the stop state of
its associated
inplace_stop_source object (
[stopsource.inplace]),
if any
. 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;
bool stop_requested() const noexcept;
bool stop_possible() const noexcept;
void swap(inplace_stop_token&) noexcept;
private:
const inplace_stop_source* stop-source = nullptr;
};
}
void swap(inplace_stop_token& rhs) noexcept;
Effects: Exchanges the values of
stop-source and
rhs.stop-source. bool stop_requested() const noexcept;
Effects: Equivalent to:
return stop-source != nullptr && stop-source->stop_requested();
[
Note 1:
As specified in
[basic.life],
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
. —
end note]
stop_possible() const noexcept;
[
Note 2:
As specified in
[basic.stc.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
. —
end note]
namespace std {
class inplace_stop_source {
public:
constexpr 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();
constexpr inplace_stop_token get_token() const noexcept;
static constexpr bool stop_possible() noexcept { return true; }
bool stop_requested() const noexcept;
bool request_stop() noexcept;
};
}
constexpr inplace_stop_source() noexcept;
Postconditions:
stop_requested() is
false. constexpr inplace_stop_token get_token() const noexcept;
Returns: A new associated
inplace_stop_token object
whose
stop-source member is equal to
this. bool stop_requested() const noexcept;
Returns:
true if the stop state inside
*this
has received a stop request; otherwise,
false. bool request_stop() noexcept;
Postconditions:
stop_requested() is
true. namespace std {
template<class CallbackFn>
class inplace_stop_callback {
public:
using callback_type = CallbackFn;
template<class Initializer>
explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
~inplace_stop_callback();
inplace_stop_callback(inplace_stop_callback&&) = delete;
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;
};
template<class CallbackFn>
inplace_stop_callback(inplace_stop_token, CallbackFn)
-> inplace_stop_callback<CallbackFn>;
}
For an
inplace_stop_callback<CallbackFn> object,
the exposition-only
callback-fn member is
its associated callback function (
[stoptoken.concepts])
. template<class Initializer>
explicit inplace_stop_callback(inplace_stop_token st, Initializer&& init)
noexcept(is_nothrow_constructible_v<CallbackFn, Initializer>);
Effects: Initializes
callback-fn with
std::forward<Initializer>(init)
and executes a stoppable callback registration (
[stoptoken.concepts])
. ~inplace_stop_callback();