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. 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 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 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