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 Clock, class Duration, class Predicate>
19 // bool wait_until(Lock& lock, stop_token stoken,
20 // const chrono::time_point<Clock, Duration>& abs_time, Predicate pred);
25 #include <condition_variable>
28 #include <shared_mutex>
32 #include "make_test_thread.h"
33 #include "test_macros.h"
35 template <class Mutex
, class Lock
>
37 const auto past
= std::chrono::steady_clock::now() - std::chrono::hours(1);
38 const auto future
= std::chrono::steady_clock::now() + std::chrono::hours(1);
40 // stop_requested before hand
43 std::condition_variable_any cv
;
48 // [Note 4: The returned value indicates whether the predicate evaluated to true
49 // regardless of whether the timeout was triggered or a stop request was made.]
50 std::same_as
<bool> auto r1
= cv
.wait_until(lock
, ss
.get_token(), past
, []() { return false; });
53 std::same_as
<bool> auto r2
= cv
.wait_until(lock
, ss
.get_token(), future
, []() { return false; });
56 std::same_as
<bool> auto r3
= cv
.wait_until(lock
, ss
.get_token(), past
, []() { return true; });
59 std::same_as
<bool> auto r4
= cv
.wait_until(lock
, ss
.get_token(), future
, []() { return true; });
62 // Postconditions: lock is locked by the calling thread.
63 assert(lock
.owns_lock());
66 // no stop request, pred was true
69 std::condition_variable_any cv
;
73 std::same_as
<bool> auto r1
= cv
.wait_until(lock
, ss
.get_token(), past
, []() { return true; });
76 std::same_as
<bool> auto r2
= cv
.wait_until(lock
, ss
.get_token(), future
, []() { return true; });
80 // no stop request, pred was false, abs_time was in the past
83 std::condition_variable_any cv
;
87 std::same_as
<bool> auto r1
= cv
.wait_until(lock
, ss
.get_token(), past
, []() { return false; });
91 // no stop request, pred was false until timeout
94 std::condition_variable_any cv
;
98 auto oldTime
= std::chrono::steady_clock::now();
100 std::same_as
<bool> auto r1
=
101 cv
.wait_until(lock
, ss
.get_token(), oldTime
+ std::chrono::milliseconds(2), [&]() { return false; });
103 assert((std::chrono::steady_clock::now() - oldTime
) >= std::chrono::milliseconds(2));
107 // no stop request, pred was false, changed to true before timeout
110 std::condition_variable_any cv
;
115 auto thread
= support::make_test_thread([&]() {
116 std::this_thread::sleep_for(std::chrono::milliseconds(2));
122 std::same_as
<bool> auto r1
= cv
.wait_until(lock
, ss
.get_token(), future
, [&]() { return flag
; });
129 // stop request comes while waiting
132 std::condition_variable_any cv
;
136 std::atomic_bool start
= false;
137 std::atomic_bool done
= false;
138 auto thread
= support::make_test_thread([&]() {
144 std::this_thread::sleep_for(std::chrono::milliseconds(2));
148 std::same_as
<bool> auto r
= cv
.wait_until(lock
, ss
.get_token(), future
, [&]() {
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_until(lock
, ss
.get_token(), future
, []() -> 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
>>();