1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // UNSUPPORTED: libcpp-has-no-threads
11 
12 // <shared_mutex>
13 
14 // template <class Mutex> class shared_lock;
15 
16 // template <class Clock, class Duration>
17 //   bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
18 
19 #include <shared_mutex>
20 #include <cassert>
21 
22 #if _LIBCPP_STD_VER > 11
23 
24 bool try_lock_until_called = false;
25 
26 struct mutex
27 {
28     template <class Clock, class Duration>
try_lock_shared_untilmutex29         bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& abs_time)
30     {
31         typedef std::chrono::milliseconds ms;
32         assert(Clock::now() - abs_time < ms(5));
33         try_lock_until_called = !try_lock_until_called;
34         return try_lock_until_called;
35     }
unlock_sharedmutex36     void unlock_shared() {}
37 };
38 
39 mutex m;
40 
41 #endif  // _LIBCPP_STD_VER > 11
42 
main()43 int main()
44 {
45 #if _LIBCPP_STD_VER > 11
46     typedef std::chrono::steady_clock Clock;
47     std::shared_lock<mutex> lk(m, std::defer_lock);
48     assert(lk.try_lock_until(Clock::now()) == true);
49     assert(try_lock_until_called == true);
50     assert(lk.owns_lock() == true);
51     try
52     {
53         lk.try_lock_until(Clock::now());
54         assert(false);
55     }
56     catch (std::system_error& e)
57     {
58         assert(e.code().value() == EDEADLK);
59     }
60     lk.unlock();
61     assert(lk.try_lock_until(Clock::now()) == false);
62     assert(try_lock_until_called == false);
63     assert(lk.owns_lock() == false);
64     lk.release();
65     try
66     {
67         lk.try_lock_until(Clock::now());
68         assert(false);
69     }
70     catch (std::system_error& e)
71     {
72         assert(e.code().value() == EPERM);
73     }
74 #endif  // _LIBCPP_STD_VER > 11
75 }
76