summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp67
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/once.hpp190
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp5
-rw-r--r--3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp7
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;
}