32 Thread support library [thread]

32.3 Stop tokens [thread.stoptoken]

32.3.4 Class stop_­source [stopsource]

The class stop_­source implements the semantics of making a stop request.
A stop request made on a stop_­source object is visible to all associated stop_­source and stop_­token ([stoptoken]) objects.
Once a stop request has been made it cannot be withdrawn (a subsequent stop request has no effect).
namespace std {
  // no-shared-stop-state indicator
  struct nostopstate_t {
    explicit nostopstate_t() = default;
  };
  inline constexpr nostopstate_t nostopstate{};

  class stop_source {
  public:
    // [stopsource.cons], constructors, copy, and assignment
    stop_source();
    explicit stop_source(nostopstate_t) noexcept;

    stop_source(const stop_source&) noexcept;
    stop_source(stop_source&&) noexcept;
    stop_source& operator=(const stop_source&) noexcept;
    stop_source& operator=(stop_source&&) noexcept;
    ~stop_source();
    void swap(stop_source&) noexcept;

    // [stopsource.mem], stop handling
    [[nodiscard]] stop_token get_token() const noexcept;
    [[nodiscard]] bool stop_possible() const noexcept;
    [[nodiscard]] bool stop_requested() const noexcept;
    bool request_stop() noexcept;

    [[nodiscard]] friend bool
      operator==(const stop_source& lhs, const stop_source& rhs) noexcept;
    friend void swap(stop_source& lhs, stop_source& rhs) noexcept;
  };
}

32.3.4.1 Constructors, copy, and assignment [stopsource.cons]

stop_source();
Effects: Initialises *this to have ownership of a new stop state.
Postconditions: stop_­possible() is true and stop_­requested() is false.
Throws: bad_­alloc if memory could not be allocated for the stop state.
explicit stop_source(nostopstate_t) noexcept;
Postconditions: stop_­possible() is false and stop_­requested() is false.
[Note
:
No resources are allocated for the state.
— end note
]
stop_source(const stop_source& rhs) noexcept;
Postconditions: *this == rhs is true.
[Note
:
*this and rhs share the ownership of the same stop state, if any.
— end note
]
stop_source(stop_source&& rhs) noexcept;
Postconditions: *this contains the value of rhs prior to the start of construction and rhs.stop_­possible() is false.
~stop_source();
Effects: Releases ownership of the stop state, if any.
stop_source& operator=(const stop_source& rhs) noexcept;
Effects: Equivalent to: stop_­source(rhs).swap(*this).
Returns: *this.
stop_source& operator=(stop_source&& rhs) noexcept;
Effects: Equivalent to: stop_­source(std​::​move(rhs)).swap(*this).
Returns: *this.
void swap(stop_source& rhs) noexcept;
Effects: Exchanges the values of *this and rhs.

32.3.4.2 Members [stopsource.mem]

[[nodiscard]] stop_token get_token() const noexcept;
Returns: stop_­token() if stop_­possible() is false; otherwise a new associated stop_­token object.
[[nodiscard]] bool stop_possible() const noexcept;
Returns: true if *this has ownership of a stop state; otherwise, false.
[[nodiscard]] bool stop_requested() const noexcept;
Returns: true if *this has ownership of a stop state that has received a stop request; otherwise, false.
bool request_stop() noexcept;
Effects: If *this does not have ownership of a stop state, returns false.
Otherwise, atomically determines whether the owned stop state has received a stop request, and if not, makes a stop request.
The determination and making of the stop request are an atomic read-modify-write operation ([intro.races]).
If the request was made, the callbacks registered by associated stop_­callback objects are synchronously called.
If an invocation of a callback exits via an exception then terminate is called ([except.terminate]).
[Note
:
A stop request includes notifying all condition variables of type condition_­variable_­any temporarily registered during an interruptible wait ([thread.condvarany.intwait]).
— end note
]
Postconditions: stop_­possible() is false or stop_­requested() is true.
Returns: true if this call made a stop request; otherwise false.

32.3.4.3 Non-member functions [stopsource.nonmembers]

[[nodiscard]] friend bool operator==(const stop_source& lhs, const stop_source& rhs) noexcept;
Returns: true if lhs and rhs have ownership of the same stop state or if both lhs and rhs do not have ownership of a stop state; otherwise false.
friend void swap(stop_source& x, stop_source& y) noexcept;
Effects: Equivalent to: x.swap(y).