diff options
Diffstat (limited to 'boost/thread/pthread/shared_mutex.hpp')
-rw-r--r-- | boost/thread/pthread/shared_mutex.hpp | 241 |
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; |