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