xref: /llvm-project/libcxx/test/std/thread/thread.stoptoken/stoptoken/stop_possible.pass.cpp (revision 121ed5c1985356436d0040dbe81bca26992b1fae)
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_possible() const noexcept;
14 // Returns: false if:
15 //    - *this does not have ownership of a stop state, or
16 //    - a stop request was not made and there are no associated stop_source objects;
17 // otherwise, true.
18 
19 #include <cassert>
20 #include <concepts>
21 #include <optional>
22 #include <stop_token>
23 #include <type_traits>
24 
25 #include "make_test_thread.h"
26 #include "test_macros.h"
27 
28 template <class T>
29 concept IsStopPossibleNoexcept = requires(const T& t) {
30   { t.stop_possible() } noexcept;
31 };
32 
33 static_assert(IsStopPossibleNoexcept<std::stop_token>);
34 
35 int main(int, char**) {
36   // no state
37   {
38     const std::stop_token st;
39     assert(!st.stop_possible());
40   }
41 
42   // a stop request was not made and there are no associated stop_source objects
43   {
44     std::optional<std::stop_source> ss{std::in_place};
45     const auto st = ss->get_token();
46     ss.reset();
47 
48     assert(!st.stop_possible());
49   }
50 
51   // a stop request was not made, but there is an associated stop_source objects
52   {
53     std::stop_source ss;
54     const auto st = ss.get_token();
55     assert(st.stop_possible());
56   }
57 
58   // a stop request was made and there are no associated stop_source objects
59   {
60     std::optional<std::stop_source> ss{std::in_place};
61     const auto st = ss->get_token();
62     ss->request_stop();
63     ss.reset();
64 
65     assert(st.stop_possible());
66   }
67 
68   // a stop request was made and there is an associated stop_source objects
69   {
70     std::stop_source ss;
71     const auto st = ss.get_token();
72     ss.request_stop();
73     assert(st.stop_possible());
74   }
75 
76   // a stop request was made on a different thread and
77   // there are no associated stop_source objects
78   {
79     std::optional<std::stop_source> ss{std::in_place};
80     const auto st = ss->get_token();
81 
82     std::thread t = support::make_test_thread([&]() {
83       ss->request_stop();
84       ss.reset();
85     });
86 
87     assert(st.stop_possible());
88     t.join();
89     assert(st.stop_possible());
90 
91   }
92 
93   return 0;
94 }
95