diff --git a/include/boost/thread/locks.hpp b/include/boost/thread/locks.hpp index 6e4341ad..abbfd75b 100644 --- a/include/boost/thread/locks.hpp +++ b/include/boost/thread/locks.hpp @@ -234,6 +234,12 @@ namespace boost { try_lock(); } + template + unique_lock(Mutex& m_,TimeDuration const& target_time): + m(&m_),is_locked(false) + { + timed_lock(target_time); + } unique_lock(Mutex& m_,system_time const& target_time): m(&m_),is_locked(false) { diff --git a/test/test_mutex.cpp b/test/test_mutex.cpp index 2640aca7..8725a8fd 100644 --- a/test/test_mutex.cpp +++ b/test/test_mutex.cpp @@ -97,6 +97,86 @@ struct test_trylock } }; +template +struct test_lock_times_out_if_other_thread_has_lock +{ + typedef boost::unique_lock Lock; + + Mutex m; + boost::mutex done_mutex; + bool done; + bool locked; + boost::condition_variable done_cond; + + test_lock_times_out_if_other_thread_has_lock(): + done(false),locked(false) + {} + + void locking_thread() + { + Lock lock(m,boost::defer_lock); + lock.timed_lock(boost::posix_time::milliseconds(50)); + + boost::lock_guard lk(done_mutex); + locked=lock.owns_lock(); + done=true; + done_cond.notify_one(); + } + + void locking_thread_through_constructor() + { + Lock lock(m,boost::posix_time::milliseconds(50)); + + boost::lock_guard lk(done_mutex); + locked=lock.owns_lock(); + done=true; + done_cond.notify_one(); + } + + bool is_done() const + { + return done; + } + + typedef test_lock_times_out_if_other_thread_has_lock this_type; + + void do_test(void (this_type::*test_func)()) + { + Lock lock(m); + + locked=false; + done=false; + + boost::thread t(test_func,this); + + try + { + { + boost::mutex::scoped_lock lk(done_mutex); + BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2), + boost::bind(&this_type::is_done,this))); + BOOST_CHECK(!locked); + } + + lock.unlock(); + t.join(); + } + catch(...) + { + lock.unlock(); + t.join(); + throw; + } + } + + + void operator()() + { + do_test(&this_type::locking_thread); + do_test(&this_type::locking_thread_through_constructor); + } +}; + template struct test_timedlock { @@ -181,66 +261,6 @@ struct test_recursive_lock } }; -template -struct test_lock_times_out_if_other_thread_has_lock -{ - typedef boost::unique_lock Lock; - - Mutex m; - boost::mutex done_mutex; - bool done; - bool locked; - boost::condition_variable done_cond; - - test_lock_times_out_if_other_thread_has_lock(): - done(false),locked(false) - {} - - void locking_thread() - { - Lock lock(m,boost::defer_lock); - lock.timed_lock(boost::posix_time::milliseconds(50)); - - boost::lock_guard lk(done_mutex); - locked=lock.owns_lock(); - done=true; - done_cond.notify_one(); - } - - bool is_done() const - { - return done; - } - - - void operator()() - { - Lock lock(m); - - typedef test_lock_times_out_if_other_thread_has_lock this_type; - - boost::thread t(&this_type::locking_thread,this); - - try - { - { - boost::mutex::scoped_lock lk(done_mutex); - BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2), - boost::bind(&this_type::is_done,this))); - BOOST_CHECK(!locked); - } - - lock.unlock(); - t.join(); - } - catch(...) - { - lock.unlock(); - t.join(); - throw; - } - } -}; void do_test_mutex() {