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;              }  | 
 Swift