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