diff options
Diffstat (limited to 'src/third_party/boost-1.56.0/boost/thread/win32/shared_mutex.hpp')
-rw-r--r-- | src/third_party/boost-1.56.0/boost/thread/win32/shared_mutex.hpp | 892 |
1 files changed, 0 insertions, 892 deletions
diff --git a/src/third_party/boost-1.56.0/boost/thread/win32/shared_mutex.hpp b/src/third_party/boost-1.56.0/boost/thread/win32/shared_mutex.hpp deleted file mode 100644 index 252174f69e6..00000000000 --- a/src/third_party/boost-1.56.0/boost/thread/win32/shared_mutex.hpp +++ /dev/null @@ -1,892 +0,0 @@ -#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP -#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP - -// (C) Copyright 2006-8 Anthony Williams -// (C) Copyright 2011-2012 Vicente J. Botet Escriba -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#include <boost/assert.hpp> -#include <boost/detail/interlocked.hpp> -#include <boost/thread/win32/thread_primitives.hpp> -#include <boost/static_assert.hpp> -#include <limits.h> -#include <boost/thread/thread_time.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> - -namespace boost -{ - class shared_mutex - { - private: - struct state_data - { - 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) - { - return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs); - } - }; - - - template<typename T> - T interlocked_compare_exchange(T* target,T new_value,T comparand) - { - BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long)); - long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target), - *reinterpret_cast<long*>(&new_value), - *reinterpret_cast<long*>(&comparand)); - return *reinterpret_cast<T const*>(&res); - } - - enum - { - unlock_sem = 0, - exclusive_sem = 1 - }; - - state_data state; - detail::win32::handle semaphores[2]; - detail::win32::handle upgrade_sem; - - void release_waiters(state_data old_state) - { - if(old_state.exclusive_waiting) - { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0); - } - - if(old_state.shared_waiting || old_state.exclusive_waiting) - { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); - } - } - - - public: - BOOST_THREAD_NO_COPYABLE(shared_mutex) - shared_mutex() - { - semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); - semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); - if (!semaphores[exclusive_sem]) - { - detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); - boost::throw_exception(thread_resource_error()); - } - upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); - if (!upgrade_sem) - { - detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); - detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX); - boost::throw_exception(thread_resource_error()); - } - state_data state_={0,0,0,0,0,0}; - state=state_; - } - - ~shared_mutex() - { - detail::win32::CloseHandle(upgrade_sem); - detail::win32::CloseHandle(semaphores[unlock_sem]); - detail::win32::CloseHandle(semaphores[exclusive_sem]); - } - - bool try_lock_shared() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(!new_state.exclusive && !new_state.exclusive_waiting_blocked) - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - return false; - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - return !(old_state.exclusive| old_state.exclusive_waiting_blocked); - } - - void lock_shared() - { -#if defined BOOST_THREAD_USES_DATETIME - BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel())); -#else - BOOST_VERIFY(try_lock_shared_until(chrono::steady_clock::now())); -#endif - } - -#if defined BOOST_THREAD_USES_DATETIME - template<typename TimeDuration> - bool timed_lock_shared(TimeDuration const & relative_time) - { - return timed_lock_shared(get_system_time()+relative_time); - } - bool timed_lock_shared(boost::system_time const& wait_until) - { - for(;;) - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked) - { - ++new_state.shared_waiting; - if(!new_state.shared_waiting) - { - boost::throw_exception(boost::lock_error()); - } - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - boost::throw_exception(boost::lock_error()); - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) - { - return true; - } - - unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until)); - if(res==detail::win32::timeout) - { - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked) - { - if(new_state.shared_waiting) - { - --new_state.shared_waiting; - } - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - return false; - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) - { - return true; - } - return false; - } - - BOOST_ASSERT(res==0); - } - } -#endif - -#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>& t) - { - using namespace chrono; - system_clock::time_point s_now = system_clock::now(); - typename Clock::time_point c_now = Clock::now(); - return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now)); - } - template <class Duration> - bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t) - { - using namespace chrono; - typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; - return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); - } - bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) - { - for(;;) - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked) - { - ++new_state.shared_waiting; - if(!new_state.shared_waiting) - { - boost::throw_exception(boost::lock_error()); - } - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - boost::throw_exception(boost::lock_error()); - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) - { - return true; - } - - chrono::system_clock::time_point n = chrono::system_clock::now(); - unsigned long res; - if (tp>n) { - chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n); - res=detail::win32::WaitForSingleObject(semaphores[unlock_sem], - static_cast<unsigned long>(rel_time.count())); - } else { - res=detail::win32::timeout; - } - if(res==detail::win32::timeout) - { - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked) - { - if(new_state.shared_waiting) - { - --new_state.shared_waiting; - } - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - return false; - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) - { - return true; - } - return false; - } - - BOOST_ASSERT(res==0); - } - } -#endif - - void unlock_shared() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - bool const last_reader=!--new_state.shared_count; - - if(last_reader) - { - if(new_state.upgrade) - { - new_state.upgrade=false; - new_state.exclusive=true; - } - else - { - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - } - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - if(last_reader) - { - if(old_state.upgrade) - { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0); - } - else - { - release_waiters(old_state); - } - } - break; - } - old_state=current_state; - } - } - - void lock() - { -#if defined BOOST_THREAD_USES_DATETIME - BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); -#else - BOOST_VERIFY(try_lock_until(chrono::steady_clock::now())); -#endif - } - -#if defined BOOST_THREAD_USES_DATETIME - template<typename TimeDuration> - bool timed_lock(TimeDuration const & relative_time) - { - return timed_lock(get_system_time()+relative_time); - } -#endif - - bool try_lock() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(new_state.shared_count || new_state.exclusive) - { - return false; - } - else - { - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - return true; - } - - -#if defined BOOST_THREAD_USES_DATETIME - bool timed_lock(boost::system_time const& wait_until) - { - for(;;) - { - state_data old_state=state; - - for(;;) - { - state_data new_state=old_state; - if(new_state.shared_count || new_state.exclusive) - { - ++new_state.exclusive_waiting; - if(!new_state.exclusive_waiting) - { - boost::throw_exception(boost::lock_error()); - } - - new_state.exclusive_waiting_blocked=true; - } - else - { - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!old_state.shared_count && !old_state.exclusive) - { - return true; - } - #ifndef UNDER_CE - const bool wait_all = true; - #else - const bool wait_all = false; - #endif - unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until)); - if(wait_res==detail::win32::timeout) - { - for(;;) - { - bool must_notify = false; - state_data new_state=old_state; - if(new_state.shared_count || new_state.exclusive) - { - if(new_state.exclusive_waiting) - { - if(!--new_state.exclusive_waiting) - { - new_state.exclusive_waiting_blocked=false; - must_notify = true; - } - } - } - else - { - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if (must_notify) - { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0); - } - - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - if(!old_state.shared_count && !old_state.exclusive) - { - return true; - } - return false; - } - BOOST_ASSERT(wait_res<2); - } - } -#endif -#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>& t) - { - using namespace chrono; - system_clock::time_point s_now = system_clock::now(); - typename Clock::time_point c_now = Clock::now(); - return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now)); - } - template <class Duration> - bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) - { - using namespace chrono; - typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; - return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); - } - bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) - { - for(;;) - { - state_data old_state=state; - - for(;;) - { - state_data new_state=old_state; - if(new_state.shared_count || new_state.exclusive) - { - ++new_state.exclusive_waiting; - if(!new_state.exclusive_waiting) - { - boost::throw_exception(boost::lock_error()); - } - - new_state.exclusive_waiting_blocked=true; - } - else - { - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!old_state.shared_count && !old_state.exclusive) - { - return true; - } - #ifndef UNDER_CE - const bool wait_all = true; - #else - const bool wait_all = false; - #endif - - chrono::system_clock::time_point n = chrono::system_clock::now(); - unsigned long wait_res; - if (tp>n) { - chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); - wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all, - static_cast<unsigned long>(rel_time.count())); - } else { - wait_res=detail::win32::timeout; - } - if(wait_res==detail::win32::timeout) - { - for(;;) - { - bool must_notify = false; - state_data new_state=old_state; - if(new_state.shared_count || new_state.exclusive) - { - if(new_state.exclusive_waiting) - { - if(!--new_state.exclusive_waiting) - { - new_state.exclusive_waiting_blocked=false; - must_notify = true; - } - } - } - else - { - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if (must_notify) - { - BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0); - } - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - if(!old_state.shared_count && !old_state.exclusive) - { - return true; - } - return false; - } - BOOST_ASSERT(wait_res<2); - } - } -#endif - - void unlock() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - new_state.exclusive=false; - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - release_waiters(old_state); - } - - void lock_upgrade() - { - for(;;) - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) - { - ++new_state.shared_waiting; - if(!new_state.shared_waiting) - { - boost::throw_exception(boost::lock_error()); - } - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - boost::throw_exception(boost::lock_error()); - } - new_state.upgrade=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - - if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade)) - { - return; - } - - BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite)); - } - } - - bool try_lock_upgrade() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) - { - return false; - } - else - { - ++new_state.shared_count; - if(!new_state.shared_count) - { - return false; - } - new_state.upgrade=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - return true; - } - - void unlock_upgrade() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - new_state.upgrade=false; - bool const last_reader=!--new_state.shared_count; - - if(last_reader) - { - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - if(last_reader) - { - release_waiters(old_state); - } - // #7720 - //else { - // release_waiters(old_state); - //} - break; - } - old_state=current_state; - } - } - - void unlock_upgrade_and_lock() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - bool const last_reader=!--new_state.shared_count; - - if(last_reader) - { - new_state.upgrade=false; - new_state.exclusive=true; - } - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - if(!last_reader) - { - BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite)); - } - break; - } - old_state=current_state; - } - } - - void unlock_and_lock_upgrade() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - new_state.exclusive=false; - new_state.upgrade=true; - ++new_state.shared_count; - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - release_waiters(old_state); - } -// bool try_unlock_upgrade_and_lock() -// { -// 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) -// { -// return false; -// } -//#endif - - void unlock_and_lock_shared() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - new_state.exclusive=false; - ++new_state.shared_count; - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - release_waiters(old_state); - } - void unlock_upgrade_and_lock_shared() - { - state_data old_state=state; - for(;;) - { - state_data new_state=old_state; - new_state.upgrade=false; - if(new_state.exclusive_waiting) - { - --new_state.exclusive_waiting; - new_state.exclusive_waiting_blocked=false; - } - new_state.shared_waiting=0; - - state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); - if(current_state==old_state) - { - break; - } - old_state=current_state; - } - release_waiters(old_state); - } - - }; - typedef shared_mutex upgrade_mutex; - -} - -#include <boost/config/abi_suffix.hpp> - -#endif |