diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp | 274 |
1 files changed, 261 insertions, 13 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index bc26282..cf45188 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -2,6 +2,7 @@ #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP // (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,6 +13,11 @@ #include <boost/thread/mutex.hpp> #include <boost/thread/condition_variable.hpp> #include <boost/thread/detail/thread_interruption.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp> #include <boost/config/abi_prefix.hpp> @@ -27,7 +33,7 @@ namespace boost bool upgrade; bool exclusive_waiting_blocked; }; - + state_data state; @@ -41,9 +47,10 @@ namespace boost exclusive_cond.notify_one(); shared_cond.notify_all(); } - public: + BOOST_THREAD_NO_COPYABLE(shared_mutex) + shared_mutex() { state_data state_={0,0,0,0}; @@ -58,7 +65,7 @@ namespace boost { boost::this_thread::disable_interruption do_not_disturb; boost::mutex::scoped_lock lk(state_change); - + while(state.exclusive || state.exclusive_waiting_blocked) { shared_cond.wait(lk); @@ -69,7 +76,7 @@ namespace boost bool try_lock_shared() { boost::mutex::scoped_lock lk(state_change); - + if(state.exclusive || state.exclusive_waiting_blocked) { return false; @@ -85,7 +92,7 @@ namespace boost { boost::this_thread::disable_interruption do_not_disturb; boost::mutex::scoped_lock lk(state_change); - + while(state.exclusive || state.exclusive_waiting_blocked) { if(!shared_cond.timed_wait(lk,timeout)) @@ -102,12 +109,34 @@ namespace boost { return timed_lock_shared(get_system_time()+relative_time); } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_shared_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + while(state.exclusive || state.exclusive_waiting_blocked) + { + if(cv_status::timeout==shared_cond.wait_until(lk,abs_time)) + { + return false; + } + } + ++state.shared_count; + return true; + } +#endif void unlock_shared() { boost::mutex::scoped_lock lk(state_change); bool const last_reader=!--state.shared_count; - + if(last_reader) { if(state.upgrade) @@ -128,7 +157,7 @@ namespace boost { boost::this_thread::disable_interruption do_not_disturb; boost::mutex::scoped_lock lk(state_change); - + while(state.shared_count || state.exclusive) { state.exclusive_waiting_blocked=true; @@ -150,7 +179,7 @@ namespace boost if(state.shared_count || state.exclusive) { state.exclusive_waiting_blocked=false; - exclusive_cond.notify_one(); + release_waiters(); return false; } break; @@ -166,10 +195,41 @@ namespace boost return timed_lock(get_system_time()+relative_time); } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + + while(state.shared_count || state.exclusive) + { + 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=true; + return true; + } +#endif + bool try_lock() { boost::mutex::scoped_lock lk(state_change); - + if(state.shared_count || state.exclusive) { return false; @@ -179,7 +239,7 @@ namespace boost state.exclusive=true; return true; } - + } void unlock() @@ -228,6 +288,33 @@ namespace boost return timed_lock_upgrade(get_system_time()+relative_time); } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + if(cv_status::timeout == shared_cond.wait_until(lk,abs_time)) + { + if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) + { + return false; + } + break; + } + } + ++state.shared_count; + state.upgrade=true; + return true; + } +#endif bool try_lock_upgrade() { boost::mutex::scoped_lock lk(state_change); @@ -248,14 +335,17 @@ namespace boost boost::mutex::scoped_lock lk(state_change); state.upgrade=false; bool const last_reader=!--state.shared_count; - + if(last_reader) { state.exclusive_waiting_blocked=false; release_waiters(); + } else { + shared_cond.notify_all(); } } + // Upgrade <-> Exclusive void unlock_upgrade_and_lock() { boost::this_thread::disable_interruption do_not_disturb; @@ -278,7 +368,58 @@ namespace boost state.exclusive_waiting_blocked=false; release_waiters(); } - + + bool try_unlock_upgrade_and_lock() + { + boost::mutex::scoped_lock lk(state_change); + if( !state.exclusive + && !state.exclusive_waiting_blocked + && state.upgrade + && state.shared_count==1) + { + state.shared_count=0; + state.exclusive=true; + state.upgrade=false; + return true; + } + return false; + } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool + try_unlock_upgrade_and_lock_for( + const chrono::duration<Rep, Period>& rel_time) + { + return try_unlock_upgrade_and_lock_until( + chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool + try_unlock_upgrade_and_lock_until( + const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + if (state.shared_count != 1) + { + for (;;) + { + cv_status status = shared_cond.wait_until(lk,abs_time); + if (state.shared_count == 1) + break; + if(status == cv_status::timeout) + return false; + } + } + state.upgrade=false; + state.exclusive=true; + state.exclusive_waiting_blocked=false; + state.shared_count=0; + return true; + } +#endif + + // Shared <-> Exclusive void unlock_and_lock_shared() { boost::mutex::scoped_lock lk(state_change); @@ -287,7 +428,59 @@ namespace boost state.exclusive_waiting_blocked=false; release_waiters(); } - + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS + bool try_unlock_shared_and_lock() + { + boost::mutex::scoped_lock lk(state_change); + if( !state.exclusive + && !state.exclusive_waiting_blocked + && !state.upgrade + && state.shared_count==1) + { + state.shared_count=0; + state.exclusive=true; + return true; + } + return false; + } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool + try_unlock_shared_and_lock_for( + const chrono::duration<Rep, Period>& rel_time) + { + return try_unlock_shared_and_lock_until( + chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool + try_unlock_shared_and_lock_until( + const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + if (state.shared_count != 1) + { + for (;;) + { + cv_status status = shared_cond.wait_until(lk,abs_time); + if (state.shared_count == 1) + break; + if(status == cv_status::timeout) + return false; + } + } + state.upgrade=false; + state.exclusive=true; + state.exclusive_waiting_blocked=false; + state.shared_count=0; + return true; + } +#endif +#endif + + // Shared <-> Upgrade void unlock_upgrade_and_lock_shared() { boost::mutex::scoped_lock lk(state_change); @@ -295,7 +488,62 @@ namespace boost state.exclusive_waiting_blocked=false; release_waiters(); } + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS + bool try_unlock_shared_and_lock_upgrade() + { + boost::mutex::scoped_lock lk(state_change); + if( !state.exclusive + && !state.exclusive_waiting_blocked + && !state.upgrade + ) + { + state.upgrade=true; + return true; + } + return false; + } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool + try_unlock_shared_and_lock_upgrade_for( + const chrono::duration<Rep, Period>& rel_time) + { + return try_unlock_shared_and_lock_upgrade_until( + chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool + try_unlock_shared_and_lock_upgrade_until( + const chrono::time_point<Clock, Duration>& abs_time) + { + boost::this_thread::disable_interruption do_not_disturb; + boost::mutex::scoped_lock lk(state_change); + if( state.exclusive + || state.exclusive_waiting_blocked + || state.upgrade + ) + { + 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; + } + } + state.upgrade=true; + return true; + } +#endif +#endif }; + + typedef shared_mutex upgrade_mutex; } #include <boost/config/abi_suffix.hpp> |