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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // UNSUPPORTED: no-threads 10 // UNSUPPORTED: c++03, c++11, c++14, c++17 11 // XFAIL: availability-synchronization_library-missing 12 13 // [[nodiscard]] bool stop_requested() const noexcept; 14 // true if *this has ownership of a stop state that has received a stop request; otherwise, false. 15 16 #include <cassert> 17 #include <chrono> 18 #include <concepts> 19 #include <optional> 20 #include <stop_token> 21 #include <type_traits> 22 23 #include "make_test_thread.h" 24 #include "test_macros.h" 25 26 template <class T> 27 concept IsStopRequestedNoexcept = requires(const T& t) { 28 { t.stop_requested() } noexcept; 29 }; 30 31 static_assert(IsStopRequestedNoexcept<std::stop_source>); 32 33 int main(int, char**) { 34 // no state 35 { 36 const std::stop_source ss{std::nostopstate}; 37 assert(!ss.stop_requested()); 38 } 39 40 // has state 41 { 42 std::stop_source ss; 43 assert(!ss.stop_requested()); 44 45 ss.request_stop(); 46 assert(ss.stop_requested()); 47 } 48 49 // request from another instance with same state 50 { 51 std::stop_source ss1; 52 auto ss2 = ss1; 53 ss2.request_stop(); 54 assert(ss1.stop_requested()); 55 } 56 57 // request from another instance with different state 58 { 59 std::stop_source ss1; 60 std::stop_source ss2; 61 62 ss2.request_stop(); 63 assert(!ss1.stop_requested()); 64 } 65 66 // multiple threads 67 { 68 std::stop_source ss; 69 70 std::thread t = support::make_test_thread([&]() { ss.request_stop(); }); 71 72 t.join(); 73 assert(ss.stop_requested()); 74 } 75 76 // [thread.stopsource.intro] A call to request_stop that returns true 77 // synchronizes with a call to stop_requested on an associated stop_source 78 // or stop_source object that returns true. 79 { 80 std::stop_source ss; 81 82 bool flag = false; 83 84 std::thread t = support::make_test_thread([&]() { 85 using namespace std::chrono_literals; 86 std::this_thread::sleep_for(1ms); 87 88 // happens-before request_stop 89 flag = true; 90 auto b = ss.request_stop(); 91 assert(b); 92 }); 93 94 while (!ss.stop_requested()) { 95 std::this_thread::yield(); 96 } 97 98 // write should be visible to the current thread 99 assert(flag == true); 100 101 t.join(); 102 } 103 104 return 0; 105 } 106