Index: include/shared_mutex =================================================================== --- include/shared_mutex +++ include/shared_mutex @@ -193,6 +193,7 @@ if (__status == cv_status::timeout) { __state_ &= ~__write_entered_; + __gate1_.notify_all(); return false; } } Index: test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp =================================================================== --- /dev/null +++ test/std/thread/thread.mutex/thread.mutex.requirements/thread.sharedtimedmutex.requirements/thread.sharedtimedmutex.class/try_lock_until_deadlock_bug.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// UNSUPPORTED: libcpp-has-no-threads +// UNSUPPORTED: c++03, c++98, c++11 + +// + +// class shared_timed_mutex; + +#include + +#include +#include +#include +#include +#include + +std::shared_timed_mutex m; + +const int total_readers = 2; +std::atomic readers_started(0); +std::atomic readers_finished(0); + +// Wait for the readers to start then try and acquire the write lock. +void writer_one() { + while (readers_started != total_readers) {} + bool b = m.try_lock_for(std::chrono::milliseconds(500)); + assert(b == false); +} + +void blocked_reader() { + ++readers_started; + // Wait until writer_one is waiting for the write lock. + while (m.try_lock_shared()) { + m.unlock_shared(); + } + // Attempt to get the read lock. writer_one should be blocking us because + // writer_one is blocked by main. + m.lock_shared(); + ++readers_finished; + m.unlock_shared(); +} + +int main() +{ + typedef std::chrono::steady_clock Clock; + + m.lock_shared(); + std::thread t1(writer_one); + // create some readers + std::thread t2(blocked_reader); + std::thread t3(blocked_reader); + // Kill the test after 10 seconds if it hasn't completed. + auto end_point = Clock::now() + std::chrono::seconds(10); + while (readers_finished != total_readers && Clock::now() < end_point) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + assert(readers_finished == total_readers); + m.unlock_shared(); + t1.join(); + t2.join(); + t3.join(); +}