summaryrefslogtreecommitdiff
path: root/boost/thread/pthread/shared_mutex.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/thread/pthread/shared_mutex.hpp')
-rw-r--r--boost/thread/pthread/shared_mutex.hpp241
1 files changed, 84 insertions, 157 deletions
diff --git a/boost/thread/pthread/shared_mutex.hpp b/boost/thread/pthread/shared_mutex.hpp
index e4ec24fe3f..ed9a296f2e 100644
--- a/boost/thread/pthread/shared_mutex.hpp
+++ b/boost/thread/pthread/shared_mutex.hpp
@@ -9,6 +9,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
#include <boost/assert.hpp>
+#include <boost/bind.hpp>
#include <boost/static_assert.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/condition_variable.hpp>
@@ -78,11 +79,6 @@ namespace boost
return ! (shared_count || exclusive);
}
- void exclusive_blocked (bool blocked)
- {
- exclusive_waiting_blocked = blocked;
- }
-
void lock ()
{
exclusive = true;
@@ -99,17 +95,19 @@ namespace boost
return ! (exclusive || exclusive_waiting_blocked);
}
- bool more_shared () const
+ bool no_shared () const
{
- return shared_count > 0 ;
+ return shared_count==0;
}
- unsigned get_shared_count () const
+
+ bool one_shared () const
{
- return shared_count ;
+ return shared_count==1;
}
- unsigned lock_shared ()
+
+ void lock_shared ()
{
- return ++shared_count;
+ ++shared_count;
}
@@ -118,18 +116,6 @@ namespace boost
--shared_count;
}
- bool unlock_shared_downgrades()
- {
- if (upgrade) {
- upgrade=false;
- exclusive=true;
- return true;
- } else {
- exclusive_waiting_blocked=false;
- return false;
- }
- }
-
void lock_upgrade ()
{
++shared_count;
@@ -185,10 +171,7 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(!state.can_lock_shared())
- {
- shared_cond.wait(lk);
- }
+ shared_cond.wait(lk, boost::bind(&state_data::can_lock_shared, boost::ref(state)));
state.lock_shared();
}
@@ -211,13 +194,9 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
-
- while(!state.can_lock_shared())
+ if(!shared_cond.timed_wait(lk, timeout, boost::bind(&state_data::can_lock_shared, boost::ref(state))))
{
- if(!shared_cond.timed_wait(lk,timeout))
- {
- return false;
- }
+ return false;
}
state.lock_shared();
return true;
@@ -226,7 +205,16 @@ namespace boost
template<typename TimeDuration>
bool timed_lock_shared(TimeDuration const & relative_time)
{
- return timed_lock_shared(get_system_time()+relative_time);
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!shared_cond.timed_wait(lk, relative_time, boost::bind(&state_data::can_lock_shared, boost::ref(state))))
+ {
+ return false;
+ }
+ state.lock_shared();
+ return true;
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -242,14 +230,9 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
-
- while(!state.can_lock_shared())
- //while(state.exclusive || state.exclusive_waiting_blocked)
+ if(!shared_cond.wait_until(lk, abs_time, boost::bind(&state_data::can_lock_shared, boost::ref(state))))
{
- if(cv_status::timeout==shared_cond.wait_until(lk,abs_time))
- {
- return false;
- }
+ return false;
}
state.lock_shared();
return true;
@@ -260,11 +243,11 @@ namespace boost
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
state.unlock_shared();
- if (! state.more_shared())
+ if (state.no_shared())
{
if (state.upgrade)
{
- // As there is a thread doing a unlock_upgrade_and_lock that is waiting for ! state.more_shared()
+ // As there is a thread doing a unlock_upgrade_and_lock that is waiting for state.no_shared()
// avoid other threads to lock, lock_upgrade or lock_shared, so only this thread is notified.
state.upgrade=false;
state.exclusive=true;
@@ -286,12 +269,8 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
-
- while (state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=true;
- exclusive_cond.wait(lk);
- }
+ state.exclusive_waiting_blocked=true;
+ exclusive_cond.wait(lk, boost::bind(&state_data::can_lock, boost::ref(state)));
state.exclusive=true;
}
@@ -302,20 +281,12 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
-
- while(state.shared_count || state.exclusive)
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.timed_wait(lk, timeout, boost::bind(&state_data::can_lock, boost::ref(state))))
{
- state.exclusive_waiting_blocked=true;
- if(!exclusive_cond.timed_wait(lk,timeout))
- {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=false;
- release_waiters();
- return false;
- }
- break;
- }
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
}
state.exclusive=true;
return true;
@@ -324,7 +295,19 @@ namespace boost
template<typename TimeDuration>
bool timed_lock(TimeDuration const & relative_time)
{
- return timed_lock(get_system_time()+relative_time);
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.timed_wait(lk, relative_time, boost::bind(&state_data::can_lock, boost::ref(state))))
+ {
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
+ }
+ state.exclusive=true;
+ return true;
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -340,20 +323,12 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
-
- while(state.shared_count || state.exclusive)
+ state.exclusive_waiting_blocked=true;
+ if(!exclusive_cond.wait_until(lk, abs_time, boost::bind(&state_data::can_lock, boost::ref(state))))
{
- state.exclusive_waiting_blocked=true;
- if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time))
- {
- if(state.shared_count || state.exclusive)
- {
- state.exclusive_waiting_blocked=false;
- release_waiters();
- return false;
- }
- break;
- }
+ state.exclusive_waiting_blocked=false;
+ release_waiters();
+ return false;
}
state.exclusive=true;
return true;
@@ -363,17 +338,12 @@ namespace boost
bool try_lock()
{
boost::unique_lock<boost::mutex> lk(state_change);
-
- if(state.shared_count || state.exclusive)
+ if(!state.can_lock())
{
return false;
}
- else
- {
- state.exclusive=true;
- return true;
- }
-
+ state.exclusive=true;
+ return true;
}
void unlock()
@@ -392,10 +362,7 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
- {
- shared_cond.wait(lk);
- }
+ shared_cond.wait(lk, boost::bind(&state_data::can_lock_upgrade, boost::ref(state)));
state.lock_shared();
state.upgrade=true;
}
@@ -407,16 +374,9 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!shared_cond.timed_wait(lk, timeout, boost::bind(&state_data::can_lock_upgrade, boost::ref(state))))
{
- if(!shared_cond.timed_wait(lk,timeout))
- {
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
- {
- return false;
- }
- break;
- }
+ return false;
}
state.lock_shared();
state.upgrade=true;
@@ -426,7 +386,17 @@ namespace boost
template<typename TimeDuration>
bool timed_lock_upgrade(TimeDuration const & relative_time)
{
- return timed_lock_upgrade(get_system_time()+relative_time);
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ boost::this_thread::disable_interruption do_not_disturb;
+#endif
+ boost::unique_lock<boost::mutex> lk(state_change);
+ if(!shared_cond.timed_wait(lk, relative_time, boost::bind(&state_data::can_lock_upgrade, boost::ref(state))))
+ {
+ return false;
+ }
+ state.lock_shared();
+ state.upgrade=true;
+ return true;
}
#endif
#ifdef BOOST_THREAD_USES_CHRONO
@@ -442,16 +412,9 @@ namespace boost
boost::this_thread::disable_interruption do_not_disturb;
#endif
boost::unique_lock<boost::mutex> lk(state_change);
- while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!shared_cond.wait_until(lk, abs_time, boost::bind(&state_data::can_lock_upgrade, boost::ref(state))))
{
- if(cv_status::timeout == shared_cond.wait_until(lk,abs_time))
- {
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
- {
- return false;
- }
- break;
- }
+ return false;
}
state.lock_shared();
state.upgrade=true;
@@ -461,17 +424,14 @@ namespace boost
bool try_lock_upgrade()
{
boost::unique_lock<boost::mutex> lk(state_change);
- if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade)
+ if(!state.can_lock_upgrade())
{
return false;
}
- else
- {
- state.lock_shared();
- state.upgrade=true;
- state.assert_lock_upgraded();
- return true;
- }
+ state.lock_shared();
+ state.upgrade=true;
+ state.assert_lock_upgraded();
+ return true;
}
void unlock_upgrade()
@@ -479,7 +439,7 @@ namespace boost
boost::unique_lock<boost::mutex> lk(state_change);
//state.upgrade=false;
state.unlock_upgrade();
- if(! state.more_shared() )
+ if(state.no_shared())
{
state.exclusive_waiting_blocked=false;
release_waiters();
@@ -497,10 +457,7 @@ namespace boost
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
state.unlock_shared();
- while (state.more_shared())
- {
- upgrade_cond.wait(lk);
- }
+ upgrade_cond.wait(lk, boost::bind(&state_data::no_shared, boost::ref(state)));
state.upgrade=false;
state.exclusive=true;
state.assert_locked();
@@ -554,16 +511,9 @@ namespace boost
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_upgraded();
- if (state.shared_count != 1)
+ if(!shared_cond.wait_until(lk, abs_time, boost::bind(&state_data::one_shared, boost::ref(state))))
{
- for (;;)
- {
- cv_status status = shared_cond.wait_until(lk,abs_time);
- if (state.shared_count == 1)
- break;
- if(status == cv_status::timeout)
- return false;
- }
+ return false;
}
state.upgrade=false;
state.exclusive=true;
@@ -619,16 +569,9 @@ namespace boost
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
- if (state.shared_count != 1)
+ if(!shared_cond.wait_until(lk, abs_time, boost::bind(&state_data::one_shared, boost::ref(state))))
{
- for (;;)
- {
- cv_status status = shared_cond.wait_until(lk,abs_time);
- if (state.shared_count == 1)
- break;
- if(status == cv_status::timeout)
- return false;
- }
+ return false;
}
state.upgrade=false;
state.exclusive=true;
@@ -654,10 +597,7 @@ namespace boost
{
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
- if( !state.exclusive
- && !state.exclusive_waiting_blocked
- && !state.upgrade
- )
+ if(state.can_lock_upgrade())
{
state.upgrade=true;
return true;
@@ -683,22 +623,9 @@ namespace boost
#endif
boost::unique_lock<boost::mutex> lk(state_change);
state.assert_lock_shared();
- if( state.exclusive
- || state.exclusive_waiting_blocked
- || state.upgrade
- )
+ if(!exclusive_cond.wait_until(lk, abs_time, boost::bind(&state_data::can_lock_upgrade, boost::ref(state))))
{
- for (;;)
- {
- cv_status status = exclusive_cond.wait_until(lk,abs_time);
- if( ! state.exclusive
- && ! state.exclusive_waiting_blocked
- && ! state.upgrade
- )
- break;
- if(status == cv_status::timeout)
- return false;
- }
+ return false;
}
state.upgrade=true;
return true;