Boost logo

Boost-Commit :

From: anthony_at_[hidden]
Date: 2008-05-09 03:48:45


Author: anthonyw
Date: 2008-05-09 03:48:44 EDT (Fri, 09 May 2008)
New Revision: 45242
URL: http://svn.boost.org/trac/boost/changeset/45242

Log:
Test and fix for bug #1905
Text files modified:
   trunk/boost/thread/pthread/shared_mutex.hpp | 146 +++++++++------------------------------
   trunk/boost/thread/win32/shared_mutex.hpp | 17 ++-
   trunk/libs/thread/test/test_shared_mutex_timed_locks.cpp | 33 +++++++++
   3 files changed, 79 insertions(+), 117 deletions(-)

Modified: trunk/boost/thread/pthread/shared_mutex.hpp
==============================================================================
--- trunk/boost/thread/pthread/shared_mutex.hpp (original)
+++ trunk/boost/thread/pthread/shared_mutex.hpp 2008-05-09 03:48:44 EDT (Fri, 09 May 2008)
@@ -44,7 +44,7 @@
     public:
         shared_mutex()
         {
- state_data state_={0};
+ state_data state_={0,0,0,0};
             state=state_;
         }
 
@@ -57,23 +57,11 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked)
- {
- ++state.shared_count;
- return;
- }
-
                 shared_cond.wait(lock);
             }
+ ++state.shared_count;
         }
 
         bool try_lock_shared()
@@ -96,26 +84,15 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked)
- {
- ++state.shared_count;
- return true;
- }
-
                 if(!shared_cond.timed_wait(lock,timeout))
                 {
                     return false;
                 }
             }
+ ++state.shared_count;
+ return true;
         }
 
         template<typename TimeDuration>
@@ -150,56 +127,35 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
                 
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.shared_count || state.exclusive)
             {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=true;
- }
- else
- {
- state.exclusive=true;
- return;
- }
+ state.exclusive_waiting_blocked=true;
                 exclusive_cond.wait(lock);
             }
+ state.exclusive=true;
         }
 
         bool timed_lock(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+
+ while(state.shared_count || state.exclusive)
             {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=true;
- }
- else
- {
- state.exclusive=true;
- return true;
- }
+ state.exclusive_waiting_blocked=true;
                 if(!exclusive_cond.timed_wait(lock,timeout))
                 {
- return false;
+ if(state.shared_count || state.exclusive)
+ {
+ state.exclusive_waiting_blocked=false;
+ exclusive_cond.notify_one();
+ return false;
+ }
+ break;
                 }
             }
+ state.exclusive=true;
+ return true;
         }
 
         template<typename TimeDuration>
@@ -236,51 +192,32 @@
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
- {
- ++state.shared_count;
- state.upgrade=true;
- return;
- }
-
                 shared_cond.wait(lock);
             }
+ ++state.shared_count;
+ state.upgrade=true;
         }
 
         bool timed_lock_upgrade(system_time const& timeout)
         {
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
             {
- if(!state.exclusive && !state.exclusive_waiting_blocked && !state.upgrade)
- {
- ++state.shared_count;
- state.upgrade=true;
- return true;
- }
-
                 if(!shared_cond.timed_wait(lock,timeout))
                 {
- return false;
+ if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ {
+ return false;
+ }
+ break;
                 }
             }
+ ++state.shared_count;
+ state.upgrade=true;
+ return true;
         }
 
         template<typename TimeDuration>
@@ -322,23 +259,12 @@
             boost::this_thread::disable_interruption do_not_disturb;
             boost::mutex::scoped_lock lock(state_change);
             --state.shared_count;
-#ifdef BOOST_MSVC
-#pragma warning(push)
-#pragma warning(disable:4127)
-#endif
- while(true)
-#ifdef BOOST_MSVC
-#pragma warning(pop)
-#endif
+ while(state.shared_count)
             {
- if(!state.shared_count)
- {
- state.upgrade=false;
- state.exclusive=true;
- break;
- }
                 upgrade_cond.wait(lock);
             }
+ state.upgrade=false;
+ state.exclusive=true;
         }
 
         void unlock_and_lock_upgrade()

Modified: trunk/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- trunk/boost/thread/win32/shared_mutex.hpp (original)
+++ trunk/boost/thread/win32/shared_mutex.hpp 2008-05-09 03:48:44 EDT (Fri, 09 May 2008)
@@ -23,12 +23,12 @@
     private:
         struct state_data
         {
- unsigned shared_count:11;
- unsigned shared_waiting:11;
- unsigned exclusive:1;
- unsigned upgrade:1;
- unsigned exclusive_waiting:7;
- unsigned exclusive_waiting_blocked:1;
+ unsigned shared_count:11,
+ shared_waiting:11,
+ exclusive:1,
+ upgrade:1,
+ exclusive_waiting:7,
+ exclusive_waiting_blocked:1;
 
             friend bool operator==(state_data const& lhs,state_data const& rhs)
             {
@@ -337,7 +337,10 @@
                         {
                             if(new_state.exclusive_waiting)
                             {
- --new_state.exclusive_waiting;
+ if(!--new_state.exclusive_waiting)
+ {
+ new_state.exclusive_waiting_blocked=false;
+ }
                             }
                         }
                         else

Modified: trunk/libs/thread/test/test_shared_mutex_timed_locks.cpp
==============================================================================
--- trunk/libs/thread/test/test_shared_mutex_timed_locks.cpp (original)
+++ trunk/libs/thread/test/test_shared_mutex_timed_locks.cpp 2008-05-09 03:48:44 EDT (Fri, 09 May 2008)
@@ -218,6 +218,38 @@
     reader.join();
 }
 
+void test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held()
+{
+ boost::shared_mutex rw_mutex;
+ boost::mutex finish_mutex;
+ boost::mutex unblocked_mutex;
+ unsigned unblocked_count=0;
+ boost::mutex::scoped_lock finish_lock(finish_mutex);
+ boost::thread reader(simple_reading_thread(rw_mutex,finish_mutex,unblocked_mutex,unblocked_count));
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ CHECK_LOCKED_VALUE_EQUAL(unblocked_mutex,unblocked_count,1u);
+
+ boost::system_time const start=boost::get_system_time();
+ boost::system_time const timeout=start+boost::posix_time::milliseconds(500);
+ bool timed_lock_succeeded=rw_mutex.timed_lock(timeout);
+ BOOST_CHECK(!timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock();
+ }
+
+ boost::posix_time::milliseconds const wait_duration(500);
+ timed_lock_succeeded=rw_mutex.timed_lock_shared(wait_duration);
+ BOOST_CHECK(timed_lock_succeeded);
+ if(timed_lock_succeeded)
+ {
+ rw_mutex.unlock_shared();
+ }
+
+ finish_lock.unlock();
+ reader.join();
+}
+
 
 boost::unit_test_framework::test_suite* init_unit_test_suite(int, char*[])
 {
@@ -230,6 +262,7 @@
     test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_write_lock_held));
     test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_if_read_lock_held));
     test->add(BOOST_TEST_CASE(&test_timed_lock_succeeds_if_no_lock_held));
+ test->add(BOOST_TEST_CASE(&test_timed_lock_times_out_but_read_lock_succeeds_if_read_lock_held));
 
     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