diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
4 files changed, 174 insertions, 95 deletions
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp index 751bdbd..7c6797d 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp @@ -61,15 +61,30 @@ namespace boost void lock() { - BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); - } - bool timed_lock(::boost::system_time const& wait_until) - { - if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit)) + if(try_lock()) { - return true; + return; } long old_count=active_count; + mark_waiting_and_try_lock(old_count); + + if(old_count&lock_flag_value) + { + bool lock_acquired=false; + void* const sem=get_event(); + + do + { + BOOST_VERIFY(win32::WaitForSingleObject( + sem,::boost::detail::win32::infinite)==0); + clear_waiting_and_try_lock(old_count); + lock_acquired=!(old_count&lock_flag_value); + } + while(!lock_acquired); + } + } + void mark_waiting_and_try_lock(long& old_count) + { for(;;) { long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value); @@ -80,6 +95,33 @@ namespace boost } old_count=current; } + } + + void clear_waiting_and_try_lock(long& old_count) + { + old_count&=~lock_flag_value; + old_count|=event_set_flag_value; + for(;;) + { + long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value; + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); + if(current==old_count) + { + break; + } + old_count=current; + } + } + + + bool timed_lock(::boost::system_time const& wait_until) + { + if(try_lock()) + { + return true; + } + long old_count=active_count; + mark_waiting_and_try_lock(old_count); if(old_count&lock_flag_value) { @@ -93,18 +135,7 @@ namespace boost BOOST_INTERLOCKED_DECREMENT(&active_count); return false; } - old_count&=~lock_flag_value; - old_count|=event_set_flag_value; - for(;;) - { - long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value; - long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); - if(current==old_count) - { - break; - } - old_count=current; - } + clear_waiting_and_try_lock(old_count); lock_acquired=!(old_count&lock_flag_value); } while(!lock_acquired); diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp index a6fcc94..c25f9ab 100644 --- a/3rdParty/Boost/src/boost/thread/win32/once.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -30,81 +30,47 @@ namespace std namespace boost { - typedef long once_flag; - -#define BOOST_ONCE_INIT 0 - - namespace detail + struct once_flag { - struct win32_mutex_scoped_lock - { - void* const mutex_handle; - explicit win32_mutex_scoped_lock(void* mutex_handle_): - mutex_handle(mutex_handle_) - { - BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite)); - } - ~win32_mutex_scoped_lock() - { - BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0); - } - private: - void operator=(win32_mutex_scoped_lock&); - }; + long status; + long count; + long throw_count; + void* event_handle; -#ifdef BOOST_NO_ANSI_APIS - template <class I> - void int_to_string(I p, wchar_t* buf) + ~once_flag() { - for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + if(count) { - *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f); + BOOST_ASSERT(count==throw_count); } - *buf = 0; - } -#else - template <class I> - void int_to_string(I p, char* buf) - { - for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + + void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event_handle,0); + if(old_event) { - *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f); + ::boost::detail::win32::CloseHandle(old_event); } - *buf = 0; } -#endif + }; + +#define BOOST_ONCE_INIT {0,0,0,0} - // create a named mutex. It doesn't really matter what this name is - // as long as it is unique both to this process, and to the address of "flag": - inline void* create_once_mutex(void* flag_address) + namespace detail + { + inline void* allocate_event_handle(void*& handle) { - -#ifdef BOOST_NO_ANSI_APIS - typedef wchar_t char_type; - static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; -#else - typedef char char_type; - static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; -#endif - unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type); - unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1; - unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2; - char_type mutex_name[once_mutex_name_length]; + void* const new_handle=::boost::detail::win32::create_anonymous_event( + ::boost::detail::win32::manual_reset_event, + ::boost::detail::win32::event_initially_reset); - std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); - - BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t)); - detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length); - detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); - -#ifdef BOOST_NO_ANSI_APIS - return win32::CreateMutexW(0, 0, mutex_name); -#else - return win32::CreateMutexA(0, 0, mutex_name); -#endif + void* event_handle=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&handle, + new_handle,0); + if(event_handle) + { + ::boost::detail::win32::CloseHandle(new_handle); + return event_handle; + } + return new_handle; } - - } @@ -114,18 +80,98 @@ namespace boost // Try for a quick win: if the procedure has already been called // just skip through: long const function_complete_flag_value=0xc15730e2; + long const running_value=0x7f0725e3; + long status; + bool counted=false; + void* event_handle=0; + long throw_count=0; + + while((status=::boost::detail::interlocked_read_acquire(&flag.status)) + !=function_complete_flag_value) + { + status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0); + if(!status) + { + try + { + if(!event_handle) + { + event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + } + if(event_handle) + { + ::boost::detail::win32::ResetEvent(event_handle); + } + f(); + if(!counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + counted=true; + } + BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value); + if(!event_handle && + (::boost::detail::interlocked_read_acquire(&flag.count)>1)) + { + event_handle=::boost::detail::allocate_event_handle(flag.event_handle); + } + if(event_handle) + { + ::boost::detail::win32::SetEvent(event_handle); + } + throw_count=::boost::detail::interlocked_read_acquire(&flag.throw_count); + break; + } + catch(...) + { + if(counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.throw_count); + } + BOOST_INTERLOCKED_EXCHANGE(&flag.status,0); + if(!event_handle) + { + event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + } + if(event_handle) + { + ::boost::detail::win32::SetEvent(event_handle); + } + throw; + } + } - if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value) + if(!counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + counted=true; + status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==function_complete_flag_value) + { + break; + } + event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + if(!event_handle) + { + event_handle=::boost::detail::allocate_event_handle(flag.event_handle); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + event_handle,::boost::detail::win32::infinite)); + } + if(counted || throw_count) { - void* const mutex_handle(::boost::detail::create_once_mutex(&flag)); - BOOST_ASSERT(mutex_handle); - detail::win32::handle_manager const closer(mutex_handle); - detail::win32_mutex_scoped_lock const lock(mutex_handle); - - if(flag!=function_complete_flag_value) + if(!BOOST_INTERLOCKED_EXCHANGE_ADD(&flag.count,(counted?-1:0)-throw_count)) { - f(); - BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value); + if(!event_handle) + { + event_handle=::boost::detail::interlocked_read_acquire(&flag.event_handle); + } + if(event_handle) + { + BOOST_INTERLOCKED_EXCHANGE_POINTER(&flag.event_handle,0); + ::boost::detail::win32::CloseHandle(event_handle); + } } } } diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp index 9f8186f..b70623a 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp @@ -8,6 +8,7 @@ #include "thread_primitives.hpp" #include <stdexcept> #include <boost/assert.hpp> +#include <boost/throw_exception.hpp> #if defined( BOOST_USE_WINDOWS_H ) # include <windows.h> @@ -60,7 +61,7 @@ namespace boost void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size); if(!heap_memory) { - throw std::bad_alloc(); + boost::throw_exception(std::bad_alloc()); } return heap_memory; } @@ -86,7 +87,7 @@ namespace boost } } -#ifdef BOOST_HAS_RVALUE_REFS +#ifndef BOOST_NO_RVALUE_REFERENCES template<typename T,typename A1> inline T* heap_new(A1&& a1) { diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp index 67a1bc3..2359c38 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -11,6 +11,7 @@ // http://www.boost.org/LICENSE_1_0.txt) #include <boost/config.hpp> +#include <boost/throw_exception.hpp> #include <boost/assert.hpp> #include <boost/thread/exceptions.hpp> #include <boost/detail/interlocked.hpp> @@ -177,7 +178,7 @@ namespace boost #endif if(!res) { - throw thread_resource_error(); + boost::throw_exception(thread_resource_error()); } return res; } @@ -191,7 +192,7 @@ namespace boost #endif if(!res) { - throw thread_resource_error(); + boost::throw_exception(thread_resource_error()); } return res; } @@ -204,7 +205,7 @@ namespace boost bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0; if(!success) { - throw thread_resource_error(); + boost::throw_exception(thread_resource_error()); } return new_handle; } |