105 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// UNSUPPORTED: no-threads10// UNSUPPORTED: c++03, c++11, c++14, c++1711 12// [[nodiscard]] bool stop_requested() const noexcept;13// true if *this has ownership of a stop state that has received a stop request; otherwise, false.14 15#include <cassert>16#include <chrono>17#include <concepts>18#include <optional>19#include <stop_token>20#include <type_traits>21 22#include "make_test_thread.h"23#include "test_macros.h"24 25template <class T>26concept IsStopRequestedNoexcept = requires(const T& t) {27 { t.stop_requested() } noexcept;28};29 30static_assert(IsStopRequestedNoexcept<std::stop_source>);31 32int main(int, char**) {33 // no state34 {35 const std::stop_source ss{std::nostopstate};36 assert(!ss.stop_requested());37 }38 39 // has state40 {41 std::stop_source ss;42 assert(!ss.stop_requested());43 44 ss.request_stop();45 assert(ss.stop_requested());46 }47 48 // request from another instance with same state49 {50 std::stop_source ss1;51 auto ss2 = ss1;52 ss2.request_stop();53 assert(ss1.stop_requested());54 }55 56 // request from another instance with different state57 {58 std::stop_source ss1;59 std::stop_source ss2;60 61 ss2.request_stop();62 assert(!ss1.stop_requested());63 }64 65 // multiple threads66 {67 std::stop_source ss;68 69 std::thread t = support::make_test_thread([&]() { ss.request_stop(); });70 71 t.join();72 assert(ss.stop_requested());73 }74 75 // [thread.stopsource.intro] A call to request_stop that returns true76 // synchronizes with a call to stop_requested on an associated stop_source77 // or stop_source object that returns true.78 {79 std::stop_source ss;80 81 bool flag = false;82 83 std::thread t = support::make_test_thread([&]() {84 using namespace std::chrono_literals;85 std::this_thread::sleep_for(1ms);86 87 // happens-before request_stop88 flag = true;89 auto b = ss.request_stop();90 assert(b);91 });92 93 while (!ss.stop_requested()) {94 std::this_thread::yield();95 }96 97 // write should be visible to the current thread98 assert(flag == true);99 100 t.join();101 }102 103 return 0;104}105