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