$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: anthony_at_[hidden]
Date: 2008-07-01 12:04:44
Author: anthonyw
Date: 2008-07-01 12:04:43 EDT (Tue, 01 Jul 2008)
New Revision: 46955
URL: http://svn.boost.org/trac/boost/changeset/46955
Log:
Partial fix for issue #1867 - ensure boost::shared_mutex supports try_lock
Text files modified: 
   trunk/libs/thread/test/test_lock_concept.cpp |    98 ++++++++++++++++++++++++++++++++++++--- 
   1 files changed, 89 insertions(+), 9 deletions(-)
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-01 12:04:43 EDT (Tue, 01 Jul 2008)
@@ -7,6 +7,7 @@
 #include <boost/test/test_case_template.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
 #include <boost/thread/thread.hpp>
 #include <boost/thread/recursive_mutex.hpp>
 #include <boost/thread/condition_variable.hpp>
@@ -150,6 +151,64 @@
 };
 
 template<typename Mutex,typename Lock>
+struct test_unlocked_after_try_lock_if_other_thread_has_lock
+{
+    Mutex m;
+    boost::mutex done_mutex;
+    bool done;
+    bool locked;
+    boost::condition_variable done_cond;
+    
+    test_unlocked_after_try_lock_if_other_thread_has_lock():
+        done(false),locked(false)
+    {}
+
+    void locking_thread()
+    {
+        Lock lock(m,boost::defer_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()()
+    {
+        Lock lock(m);
+
+        typedef test_unlocked_after_try_lock_if_other_thread_has_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_throws_if_lock_called_when_already_locked
 {
     void operator()() const
@@ -223,12 +282,9 @@
     }
 };
 
-
-
-BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
+template<typename Mutex,typename Lock>
+void test_lock_is_scoped_lock_concept_for_mutex()
 {
-    typedef typename Mutex::scoped_lock Lock;
-    
     test_default_constructed_has_no_mutex_and_unlocked<Lock>()();
     test_initially_locked<Mutex,Lock>()();
     test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
@@ -238,6 +294,24 @@
     test_throws_if_lock_called_when_already_locked<Mutex,Lock>()();
     test_throws_if_unlock_called_when_already_unlocked<Mutex,Lock>()();
     test_locks_can_be_swapped<Mutex,Lock>()();
+    test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_throws_if_try_lock_called_when_already_locked<Mutex,Lock>()();
+    test_unlocked_after_try_lock_if_other_thread_has_lock<Mutex,Lock>()();
+}
+
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_lock_concept,Mutex)
+{
+    typedef typename Mutex::scoped_lock Lock;
+
+    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
+}
+
+BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_unique_lock_is_scoped_lock,Mutex)
+{
+    typedef boost::unique_lock<Mutex> Lock;
+
+    test_lock_is_scoped_lock_concept_for_mutex<Mutex,Lock>();
 }
 
 BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_scoped_try_lock_concept,Mutex)
@@ -252,6 +326,7 @@
     test_unlocked_after_unlock_called<Mutex,Lock>()();
     test_locked_after_lock_called<Mutex,Lock>()();
     test_locked_after_try_lock_called<Mutex,Lock>()();
+    test_unlocked_after_try_lock_if_other_thread_has_lock<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>()();
@@ -264,14 +339,19 @@
         BOOST_TEST_SUITE("Boost.Threads: lock concept test suite");
 
     typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
-        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types;
+        boost::recursive_mutex,boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_lock;
     
-    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types));
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_lock_concept,mutex_types_with_scoped_lock));
 
     typedef boost::mpl::vector<boost::try_mutex,boost::timed_mutex,
-        boost::recursive_try_mutex,boost::recursive_timed_mutex> try_mutex_types;
+        boost::recursive_try_mutex,boost::recursive_timed_mutex> mutex_types_with_scoped_try_lock;
+
+    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,mutex_types_with_scoped_try_lock));
 
-    test->add(BOOST_TEST_CASE_TEMPLATE(test_scoped_try_lock_concept,try_mutex_types));
+    typedef boost::mpl::vector<boost::mutex,boost::try_mutex,boost::timed_mutex,
+        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));
 
     return test;
 }