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 // UNSUPPORTED: c++03, c++98, c++11
12 
13 // <shared_mutex>
14 
15 // class shared_timed_mutex;
16 
17 #include <shared_mutex>
18 
19 #include <atomic>
20 #include <chrono>
21 #include <thread>
22 #include <cstdlib>
23 #include <cassert>
24 
25 std::shared_timed_mutex m;
26 
27 const int total_readers = 2;
28 std::atomic<int> readers_started(0);
29 std::atomic<int> readers_finished(0);
30 
31 // Wait for the readers to start then try and acquire the write lock.
writer_one()32 void writer_one() {
33   while (readers_started != total_readers) {}
34   bool b = m.try_lock_for(std::chrono::milliseconds(500));
35   assert(b == false);
36 }
37 
blocked_reader()38 void blocked_reader() {
39   ++readers_started;
40   // Wait until writer_one is waiting for the write lock.
41   while (m.try_lock_shared()) {
42     m.unlock_shared();
43   }
44   // Attempt to get the read lock. writer_one should be blocking us because
45   // writer_one is blocked by main.
46   m.lock_shared();
47   ++readers_finished;
48   m.unlock_shared();
49 }
50 
main()51 int main()
52 {
53   typedef std::chrono::steady_clock Clock;
54 
55   m.lock_shared();
56   std::thread t1(writer_one);
57   // create some readers
58   std::thread t2(blocked_reader);
59   std::thread t3(blocked_reader);
60   // Kill the test after 10 seconds if it hasn't completed.
61   auto end_point = Clock::now() + std::chrono::seconds(10);
62   while (readers_finished != total_readers && Clock::now() < end_point) {
63     std::this_thread::sleep_for(std::chrono::seconds(1));
64   }
65   assert(readers_finished == total_readers);
66   m.unlock_shared();
67   t1.join();
68   t2.join();
69   t3.join();
70 }
71