Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2008-07-07 18:04:10


Author: anthonyw
Date: 2008-07-07 18:04:10 EDT (Mon, 07 Jul 2008)
New Revision: 47197
URL: http://svn.boost.org/trac/boost/changeset/47197

Log:
test and fix for issue #2081
Text files modified:
   trunk/boost/thread/locks.hpp | 63 +++++++++++++++++
   trunk/libs/thread/test/test_lock_concept.cpp | 144 +++++++++++++++++++++++++++++++++++++++
   2 files changed, 205 insertions(+), 2 deletions(-)

Modified: trunk/boost/thread/locks.hpp
==============================================================================
--- trunk/boost/thread/locks.hpp (original)
+++ trunk/boost/thread/locks.hpp 2008-07-07 18:04:10 EDT (Mon, 07 Jul 2008)
@@ -186,6 +186,11 @@
             swap(temp);
             return *this;
         }
+ void swap(unique_lock&& other)
+ {
+ std::swap(m,other.m);
+ std::swap(is_locked,other.is_locked);
+ }
 #else
         unique_lock(detail::thread_move_t<unique_lock<Mutex> > other):
             m(other->m),is_locked(other->is_locked)
@@ -218,7 +223,6 @@
             swap(temp);
             return *this;
         }
-#endif
         void swap(unique_lock& other)
         {
             std::swap(m,other.m);
@@ -229,6 +233,7 @@
             std::swap(m,other->m);
             std::swap(is_locked,other->is_locked);
         }
+#endif
         
         ~unique_lock()
         {
@@ -313,11 +318,19 @@
         friend class upgrade_lock<Mutex>;
     };
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename Mutex>
+ void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs)
+ {
+ lhs.swap(rhs);
+ }
+#else
     template<typename Mutex>
     void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs)
     {
         lhs.swap(rhs);
     }
+#endif
 
 #ifdef BOOST_HAS_RVALUE_REFS
     template<typename Mutex>
@@ -424,11 +437,29 @@
             return *this;
         }
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ void swap(shared_lock&& other)
+ {
+ std::swap(m,other.m);
+ std::swap(is_locked,other.is_locked);
+ }
+#else
         void swap(shared_lock& other)
         {
             std::swap(m,other.m);
             std::swap(is_locked,other.is_locked);
         }
+ void swap(boost::detail::thread_move_t<shared_lock> other)
+ {
+ std::swap(m,other->m);
+ std::swap(is_locked,other->is_locked);
+ }
+#endif
+
+ Mutex* mutex() const
+ {
+ return m;
+ }
         
         ~shared_lock()
         {
@@ -490,6 +521,20 @@
 
     };
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename Mutex>
+ void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs)
+ {
+ lhs.swap(rhs);
+ }
+#else
+ template<typename Mutex>
+ void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs)
+ {
+ lhs.swap(rhs);
+ }
+#endif
+
     template<typename Mutex>
     class upgrade_lock
     {
@@ -743,6 +788,12 @@
                 return *this;
             }
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ void swap(try_lock_wrapper&& other)
+ {
+ base::swap(other);
+ }
+#else
             void swap(try_lock_wrapper& other)
             {
                 base::swap(other);
@@ -751,6 +802,7 @@
             {
                 base::swap(*other);
             }
+#endif
 
             void lock()
             {
@@ -788,11 +840,19 @@
             }
         };
 
+#ifdef BOOST_HAS_RVALUE_REFS
+ template<typename Mutex>
+ void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs)
+ {
+ lhs.swap(rhs);
+ }
+#else
         template<typename Mutex>
         void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)
         {
             lhs.swap(rhs);
         }
+#endif
         
         template<typename MutexType1,typename MutexType2>
         unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)
@@ -1189,5 +1249,6 @@
 }
 
 #include <boost/config/abi_suffix.hpp>
+#include <boost/mpl/identity.hpp>
 
 #endif

Modified: trunk/libs/thread/test/test_lock_concept.cpp
==============================================================================
--- trunk/libs/thread/test/test_lock_concept.cpp (original)
+++ trunk/libs/thread/test/test_lock_concept.cpp 2008-07-07 18:04:10 EDT (Mon, 07 Jul 2008)
@@ -84,6 +84,122 @@
 };
 
 template<typename Mutex,typename Lock>
+struct test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m,boost::try_to_lock);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ boost::unique_lock<Mutex> lock(m);
+
+ typedef test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,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;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
+struct test_initially_locked_if_other_thread_has_shared_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_locked_if_other_thread_has_shared_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ boost::shared_lock<Mutex> lock(m);
+
+ typedef test_initially_locked_if_other_thread_has_shared_lock<Mutex,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;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
 struct test_initially_unlocked_with_defer_lock_parameter
 {
     void operator()() const
@@ -263,6 +379,8 @@
     {
         Mutex m1;
         Mutex m2;
+ Mutex m3;
+
         Lock l1(m1);
         Lock l2(m2);
 
@@ -278,7 +396,10 @@
 
         BOOST_CHECK_EQUAL(l1.mutex(),&m1);
         BOOST_CHECK_EQUAL(l2.mutex(),&m2);
-
+
+ l1.swap(Lock(m3));
+
+ BOOST_CHECK_EQUAL(l1.mutex(),&m3);
     }
 };
 
@@ -333,6 +454,26 @@
     test_locks_can_be_swapped<Mutex,Lock>()();
 }
 
+void test_shared_lock()
+{
+ typedef boost::shared_mutex Mutex;
+ typedef boost::shared_lock<Mutex> Lock;
+
+ test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
+ test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_with_try_lock_if_other_thread_has_unique_lock<Mutex,Lock>()();
+ test_initially_locked_if_other_thread_has_shared_lock<Mutex,Lock>()();
+ test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
+ test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
+ test_unlocked_after_unlock_called<Mutex,Lock>()();
+ test_locked_after_lock_called<Mutex,Lock>()();
+ test_locked_after_try_lock_called<Mutex,Lock>()();
+ test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+ test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
+ test_locks_can_be_swapped<Mutex,Lock>()();
+}
+
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
     boost::unit_test_framework::test_suite* test =
@@ -352,6 +493,7 @@
         boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex,boost::shared_mutex> all_mutex_types;
     
     test->add(BOOST_TEST_CASE_TEMPLATE(test_unique_lock_is_scoped_lock,all_mutex_types));
+ test->add(BOOST_TEST_CASE(&test_shared_lock));
 
     return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk