1 //===----------------------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: no-threads
10 // UNSUPPORTED: c++03, c++11, c++14, c++17
11 // UNSUPPORTED: libcpp-has-no-experimental-stop_token
12 // XFAIL: availability-synchronization_library-missing
14 // <condition_variable>
16 // class condition_variable_any;
18 // template<class Lock, class Predicate>
19 // bool wait(Lock& lock, stop_token stoken, Predicate pred);
23 #include <condition_variable>
26 #include <shared_mutex>
30 #include "make_test_thread.h"
31 #include "test_macros.h"
33 template <class Mutex
, class Lock
>
35 // stop_requested before hand
38 std::condition_variable_any cv
;
43 // [Note 1: The returned value indicates whether the predicate evaluated to true regardless of whether there was a stop request.]
44 std::same_as
<bool> auto r1
= cv
.wait(lock
, ss
.get_token(), []() { return false; });
47 std::same_as
<bool> auto r2
= cv
.wait(lock
, ss
.get_token(), []() { return true; });
50 // Postconditions: lock is locked by the calling thread.
51 assert(lock
.owns_lock());
57 std::condition_variable_any cv
;
60 std::same_as
<bool> auto r1
= cv
.wait(lock
, ss
.get_token(), []() { return true; });
64 auto thread
= support::make_test_thread([&]() {
65 std::this_thread::sleep_for(std::chrono::milliseconds(2));
71 std::same_as
<bool> auto r2
= cv
.wait(lock
, ss
.get_token(), [&]() { return flag
; });
76 assert(lock
.owns_lock());
79 // stop request comes while waiting
82 std::condition_variable_any cv
;
86 std::atomic_bool start
= false;
87 std::atomic_bool done
= false;
88 auto thread
= support::make_test_thread([&]() {
94 std::this_thread::sleep_for(std::chrono::milliseconds(2));
98 std::same_as
<bool> auto r
= cv
.wait(lock
, ss
.get_token(), [&]() {
107 assert(lock
.owns_lock());
110 // #76807 Hangs in std::condition_variable_any when used with std::stop_token
115 thread_
= support::make_test_jthread([this](std::stop_token st
) {
116 while (!st
.stop_requested()) {
117 std::unique_lock lock
{m_
};
118 cv_
.wait(lock
, st
, [] { return false; });
125 std::condition_variable_any cv_
;
126 std::jthread thread_
;
129 [[maybe_unused
]] MyThread my_thread
;
132 // request_stop potentially in-between check and wait
135 std::condition_variable_any cv
;
139 std::atomic_bool pred_started
= false;
140 std::atomic_bool request_stop_called
= false;
141 auto thread
= support::make_test_thread([&]() {
142 pred_started
.wait(false);
144 request_stop_called
.store(true);
145 request_stop_called
.notify_all();
148 std::same_as
<bool> auto r
= cv
.wait(lock
, ss
.get_token(), [&]() {
149 pred_started
.store(true);
150 pred_started
.notify_all();
151 request_stop_called
.wait(false);
157 assert(lock
.owns_lock());
160 #if !defined(TEST_HAS_NO_EXCEPTIONS)
161 // Throws: Any exception thrown by pred.
164 std::condition_variable_any cv
;
169 cv
.wait(lock
, ss
.get_token(), []() -> bool { throw 5; });
175 #endif //!defined(TEST_HAS_NO_EXCEPTIONS)
178 int main(int, char**) {
179 test
<std::mutex
, std::unique_lock
<std::mutex
>>();
180 test
<std::shared_mutex
, std::shared_lock
<std::shared_mutex
>>();