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// <shared_mutex>
11
12// template <class Mutex> class shared_lock;
13
14// template <class Clock, class Duration>
15//   bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
16
17#include <shared_mutex>
18#include <cassert>
19
20#if _LIBCPP_STD_VER > 11
21
22bool try_lock_until_called = false;
23
24struct mutex
25{
26    template <class Clock, class Duration>
27        bool try_lock_shared_until(const std::chrono::time_point<Clock, Duration>& abs_time)
28    {
29        typedef std::chrono::milliseconds ms;
30        assert(Clock::now() - abs_time < ms(5));
31        try_lock_until_called = !try_lock_until_called;
32        return try_lock_until_called;
33    }
34    void unlock_shared() {}
35};
36
37mutex m;
38
39#endif  // _LIBCPP_STD_VER > 11
40
41int main()
42{
43#if _LIBCPP_STD_VER > 11
44    typedef std::chrono::steady_clock Clock;
45    std::shared_lock<mutex> lk(m, std::defer_lock);
46    assert(lk.try_lock_until(Clock::now()) == true);
47    assert(try_lock_until_called == true);
48    assert(lk.owns_lock() == true);
49    try
50    {
51        lk.try_lock_until(Clock::now());
52        assert(false);
53    }
54    catch (std::system_error& e)
55    {
56        assert(e.code().value() == EDEADLK);
57    }
58    lk.unlock();
59    assert(lk.try_lock_until(Clock::now()) == false);
60    assert(try_lock_until_called == false);
61    assert(lk.owns_lock() == false);
62    lk.release();
63    try
64    {
65        lk.try_lock_until(Clock::now());
66        assert(false);
67    }
68    catch (std::system_error& e)
69    {
70        assert(e.code().value() == EPERM);
71    }
72#endif  // _LIBCPP_STD_VER > 11
73}
74