diff options
| author | Tobias Markmann <tm@ayena.de> | 2014-10-19 20:22:58 (GMT) |
|---|---|---|
| committer | Tobias Markmann <tm@ayena.de> | 2014-10-20 13:49:33 (GMT) |
| commit | 6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch) | |
| tree | 2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/thread/win32 | |
| parent | 38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff) | |
| download | swift-contrib-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip swift-contrib-6b22dfcf59474dd016a0355a3102a1dd3692d92c.tar.bz2 | |
Update Boost in 3rdParty to version 1.56.0.
This updates Boost in our 3rdParty directory to version 1.56.0.
Updated our update.sh script to stop on error.
Changed error reporting in SwiftTools/CrashReporter.cpp to SWIFT_LOG due to
missing include of <iostream> with newer Boost.
Change-Id: I4b35c77de951333979a524097f35f5f83d325edc
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
10 files changed, 1206 insertions, 155 deletions
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp index e259121..cfdfa04 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp @@ -59,4 +59,5 @@ namespace boost } } +#if defined BOOST_THREAD_USES_DATETIME bool timed_lock(::boost::system_time const& target) { @@ -69,4 +70,5 @@ namespace boost return timed_lock(get_system_time()+timeout); } +#endif #ifdef BOOST_THREAD_USES_CHRONO @@ -115,4 +117,5 @@ namespace boost } +#if defined BOOST_THREAD_USES_DATETIME bool try_timed_lock(long current_thread_id,::boost::system_time const& target) { @@ -125,4 +128,5 @@ namespace boost return false; } +#endif template <typename TP> bool try_timed_lock_until(long current_thread_id,TP const& target) 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 6a43077..01db033 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp @@ -15,5 +15,7 @@ #include <boost/thread/win32/interlocked_read.hpp> #include <boost/thread/thread_time.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/thread/xtime.hpp> +#endif #include <boost/detail/interlocked.hpp> #ifdef BOOST_THREAD_USES_CHRONO @@ -80,6 +82,8 @@ namespace boost do { - BOOST_VERIFY(win32::WaitForSingleObject( - sem,::boost::detail::win32::infinite)==0); + unsigned const retval(win32::WaitForSingleObject(sem, ::boost::detail::win32::infinite)); + BOOST_VERIFY(0 == retval || ::boost::detail::win32::wait_abandoned == retval); +// BOOST_VERIFY(win32::WaitForSingleObject( +// sem,::boost::detail::win32::infinite)==0); clear_waiting_and_try_lock(old_count); lock_acquired=!(old_count&lock_flag_value); @@ -92,8 +96,11 @@ namespace boost for(;;) { - long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value); + bool const was_locked=(old_count&lock_flag_value) ? true : false; + long const new_count=was_locked?(old_count+1):(old_count|lock_flag_value); long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); if(current==old_count) { + if(was_locked) + old_count=new_count; break; } @@ -119,4 +126,5 @@ namespace boost +#if defined BOOST_THREAD_USES_DATETIME bool timed_lock(::boost::system_time const& wait_until) { @@ -148,5 +156,4 @@ namespace boost } - template<typename Duration> bool timed_lock(Duration const& timeout) @@ -159,5 +166,5 @@ namespace boost return timed_lock(system_time(timeout)); } - +#endif #ifdef BOOST_THREAD_USES_CHRONO template <class Rep, class Period> diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp index 4c893ad..57aaf8c 100644 --- a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp @@ -12,7 +12,11 @@ #include <boost/thread/win32/interlocked_read.hpp> #include <boost/thread/cv_status.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/thread/xtime.hpp> +#endif #include <boost/thread/mutex.hpp> #include <boost/thread/thread_time.hpp> +#include <boost/thread/lock_guard.hpp> +#include <boost/thread/lock_types.hpp> #include <boost/assert.hpp> @@ -188,16 +192,15 @@ namespace boost { entry_ptr const entry; + boost::mutex& internal_mutex; BOOST_THREAD_NO_COPYABLE(entry_manager) - entry_manager(entry_ptr const& entry_): - entry(entry_) + entry_manager(entry_ptr const& entry_, boost::mutex& mutex_): + entry(entry_), internal_mutex(mutex_) {} ~entry_manager() { - if(! entry->is_notified()) - { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); entry->remove_waiter(); - } } @@ -215,5 +218,5 @@ namespace boost relocker<lock_type> locker(lock); - entry_manager entry(get_wait_entry()); + entry_manager entry(get_wait_entry(), internal_mutex); locker.unlock(); @@ -322,4 +325,5 @@ namespace boost +#if defined BOOST_THREAD_USES_DATETIME bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time) { @@ -334,5 +338,14 @@ namespace boost bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) { - return do_wait(m,wait_duration.total_milliseconds()); + if (wait_duration.is_pos_infinity()) + { + wait(m); // or do_wait(m,detail::timeout::sentinel()); + return true; + } + if (wait_duration.is_special()) + { + return true; + } + return do_wait(m,wait_duration.total_milliseconds()); } @@ -352,5 +365,5 @@ namespace boost return do_wait(m,wait_duration.total_milliseconds(),pred); } - +#endif #ifdef BOOST_THREAD_USES_CHRONO @@ -362,5 +375,9 @@ namespace boost { using namespace chrono; - do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); + chrono::time_point<Clock, Duration> now = Clock::now(); + if (t<=now) { + return cv_status::timeout; + } + do_wait(lock, ceil<milliseconds>(t-now).count()); return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; @@ -374,4 +391,8 @@ namespace boost { using namespace chrono; + if (d<=chrono::duration<Rep, Period>::zero()) { + return cv_status::timeout; + } + steady_clock::time_point c_now = steady_clock::now(); do_wait(lock, ceil<milliseconds>(d).count()); @@ -401,5 +422,5 @@ namespace boost Predicate pred) { - return wait_until(lock, chrono::steady_clock::now() + d, pred); + return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred)); } #endif @@ -429,4 +450,5 @@ namespace boost } +#if defined BOOST_THREAD_USES_DATETIME template<typename lock_type> bool timed_wait(lock_type& m,boost::system_time const& abs_time) @@ -464,4 +486,5 @@ namespace boost return do_wait(m,wait_duration.total_milliseconds(),pred); } +#endif #ifdef BOOST_THREAD_USES_CHRONO @@ -473,5 +496,9 @@ namespace boost { using namespace chrono; - do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); + chrono::time_point<Clock, Duration> now = Clock::now(); + if (t<=now) { + return cv_status::timeout; + } + do_wait(lock, ceil<milliseconds>(t-now).count()); return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; @@ -485,4 +512,7 @@ namespace boost { using namespace chrono; + if (d<=chrono::duration<Rep, Period>::zero()) { + return cv_status::timeout; + } steady_clock::time_point c_now = steady_clock::now(); do_wait(lock, ceil<milliseconds>(d).count()); @@ -513,5 +543,5 @@ namespace boost Predicate pred) { - return wait_until(lock, chrono::steady_clock::now() + d, pred); + return wait_until(lock, chrono::steady_clock::now() + d, boost::move(pred)); } #endif diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp index 85a00e2..0154478 100644 --- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp @@ -9,5 +9,8 @@ #include <boost/thread/win32/basic_timed_mutex.hpp> #include <boost/thread/exceptions.hpp> -#include <boost/thread/locks.hpp> +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS +#include <boost/thread/lock_types.hpp> +#endif +#include <boost/thread/detail/delete.hpp> #include <boost/config/abi_prefix.hpp> @@ -34,6 +37,8 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS typedef unique_lock<mutex> scoped_lock; typedef detail::try_lock_wrapper<mutex> scoped_try_lock; +#endif }; @@ -55,7 +60,9 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS typedef unique_lock<timed_mutex> scoped_timed_lock; typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock; typedef scoped_timed_lock scoped_lock; +#endif }; } diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp index 3066b50..0ed56a5 100644 --- a/3rdParty/Boost/src/boost/thread/win32/once.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -6,5 +6,5 @@ // (C) Copyright 2005-7 Anthony Williams // (C) Copyright 2005 John Maddock -// (C) Copyright 2011-2012 Vicente J. Botet Escriba +// (C) Copyright 2011-2013 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See @@ -19,4 +19,9 @@ #include <boost/thread/win32/thread_primitives.hpp> #include <boost/thread/win32/interlocked_read.hpp> +#include <boost/core/no_exceptions_support.hpp> +#include <boost/thread/detail/move.hpp> +#include <boost/thread/detail/invoke.hpp> + +#include <boost/bind.hpp> #include <boost/config/abi_prefix.hpp> @@ -32,4 +37,14 @@ namespace std namespace boost { + struct once_flag; + namespace detail + { + struct once_context; + + inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT; + inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT; + inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT; + } + #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 @@ -40,10 +55,10 @@ namespace boost : status(0), count(0) {} - private: long status; long count; - template<typename Function> - friend - void call_once(once_flag& flag,Function f); + private: + friend inline bool enter_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT; + friend inline void commit_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT; + friend inline void rollback_once_region(once_flag& flag, detail::once_context& ctx) BOOST_NOEXCEPT; }; @@ -60,4 +75,15 @@ namespace boost #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 +#if defined BOOST_THREAD_PROVIDES_INVOKE +#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke +#define BOOST_THREAD_INVOKE_RET_VOID_CALL +#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET +#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void> +#define BOOST_THREAD_INVOKE_RET_VOID_CALL +#else +#define BOOST_THREAD_INVOKE_RET_VOID boost::bind +#define BOOST_THREAD_INVOKE_RET_VOID_CALL () +#endif + namespace detail { @@ -136,7 +162,207 @@ namespace boost mutex_name); } - } + struct once_context { + long const function_complete_flag_value; + long const running_value; + bool counted; + detail::win32::handle_manager event_handle; + detail::once_char_type mutex_name[once_mutex_name_length]; + once_context() : + function_complete_flag_value(0xc15730e2), + running_value(0x7f0725e3), + counted(false) + { + mutex_name[0]=0; + } + }; + enum once_action {try_, break_, continue_}; + inline bool enter_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT + { + long status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,ctx.running_value,0); + if(!status) + { + if(!ctx.event_handle) + { + ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag); + } + if(ctx.event_handle) + { + ::boost::detail::win32::ResetEvent(ctx.event_handle); + } + return true; + } + return false; + } + inline void commit_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT + { + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + } + BOOST_INTERLOCKED_EXCHANGE(&flag.status,ctx.function_complete_flag_value); + if(!ctx.event_handle && + (::boost::detail::interlocked_read_acquire(&flag.count)>1)) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + } + if(ctx.event_handle) + { + ::boost::detail::win32::SetEvent(ctx.event_handle); + } + } + inline void rollback_once_region(once_flag& flag, once_context& ctx) BOOST_NOEXCEPT + { + BOOST_INTERLOCKED_EXCHANGE(&flag.status,0); + if(!ctx.event_handle) + { + ctx.event_handle=detail::open_once_event(ctx.mutex_name,&flag); + } + if(ctx.event_handle) + { + ::boost::detail::win32::SetEvent(ctx.event_handle); + } + } + } + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) +//#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) + inline void call_once(once_flag& flag, void (*f)()) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f(); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } +//#endif + template<typename Function> + inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f(); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, class A, class ...ArgTypes> + inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(A) a, BOOST_THREAD_RV_REF(ArgTypes)... args) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID( + thread_detail::decay_copy(boost::forward<Function>(f)), + thread_detail::decay_copy(boost::forward<A>(a)), + thread_detail::decay_copy(boost::forward<ArgTypes>(args))... + ) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } +#else +#if ! defined(BOOST_MSVC) && ! defined(BOOST_INTEL) template<typename Function> void call_once(once_flag& flag,Function f) @@ -144,84 +370,718 @@ 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; - detail::win32::handle_manager event_handle; - detail::once_char_type mutex_name[detail::once_mutex_name_length]; - mutex_name[0]=0; + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f(); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1> + void call_once(once_flag& flag,Function f, T1 p1) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2> + void call_once(once_flag& flag,Function f, T1 p1, T2 p2) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2, typename T3> + void call_once(once_flag& flag,Function f, T1 p1, T2 p2, T3 p3) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } +#elif defined BOOST_NO_CXX11_RVALUE_REFERENCES - while((status=::boost::detail::interlocked_read_acquire(&flag.status)) - !=function_complete_flag_value) + template<typename Function> + void call_once(once_flag& flag,Function const&f) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) { - status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0); - if(!status) + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f(); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) { -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1> + void call_once(once_flag& flag,Function const&f, T1 const&p1) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2> + void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2, typename T3> + void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2, T3 const&p3) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } #endif +#if 1 +#if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR) + inline void call_once(once_flag& flag, void (*f)()) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) { - if(!event_handle) + BOOST_TRY { - event_handle=detail::open_once_event(mutex_name,&flag); + f(); } - if(event_handle) + BOOST_CATCH(...) { - ::boost::detail::win32::ResetEvent(event_handle); + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW } - f(); - if(!counted) + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename T1> + void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1)), BOOST_THREAD_RV_REF(T1) p1) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f( + thread_detail::decay_copy(boost::forward<T1>(p1)) + ); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2> + void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY { - BOOST_INTERLOCKED_INCREMENT(&flag.count); - counted=true; + f( + thread_detail::decay_copy(boost::forward<T1>(p1)), + thread_detail::decay_copy(boost::forward<T2>(p2)) + ); } - BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value); - if(!event_handle && - (::boost::detail::interlocked_read_acquire(&flag.count)>1)) + BOOST_CATCH(...) { - event_handle=detail::create_once_event(mutex_name,&flag); + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW } - if(event_handle) + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) { - ::boost::detail::win32::SetEvent(event_handle); + break; } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2, typename T3> + void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f( + thread_detail::decay_copy(boost::forward<T1>(p1)), + thread_detail::decay_copy(boost::forward<T2>(p2)), + thread_detail::decay_copy(boost::forward<T3>(p3)) + ); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); break; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + if(!ctx.counted) { - BOOST_INTERLOCKED_EXCHANGE(&flag.status,0); - if(!event_handle) + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) { - event_handle=detail::open_once_event(mutex_name,&flag); + break; } - if(event_handle) + if(!ctx.event_handle) { - ::boost::detail::win32::SetEvent(event_handle); + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; } - throw; // BOOST_NO_EXCEPTIONS protected } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } #endif + template<typename Function> + void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + f(); + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } - if(!counted) + template<typename Function, typename T1> + void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID( + thread_detail::decay_copy(boost::forward<Function>(f)), + thread_detail::decay_copy(boost::forward<T1>(p1)) + ) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) { BOOST_INTERLOCKED_INCREMENT(&flag.count); - counted=true; - status=::boost::detail::interlocked_read_acquire(&flag.status); - if(status==function_complete_flag_value) + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) { break; } - if(!event_handle) + if(!ctx.event_handle) { - event_handle=detail::create_once_event(mutex_name,&flag); + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); continue; } } BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( - event_handle,::boost::detail::win32::infinite)); + ctx.event_handle,::boost::detail::win32::infinite)); } } + template<typename Function, typename T1, typename T2> + void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID( + thread_detail::decay_copy(boost::forward<Function>(f)), + thread_detail::decay_copy(boost::forward<T1>(p1)), + thread_detail::decay_copy(boost::forward<T2>(p2)) + ) BOOST_THREAD_INVOKE_RET_VOID_CALL; + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + template<typename Function, typename T1, typename T2, typename T3> + void call_once(once_flag& flag,BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + detail::once_context ctx; + while(::boost::detail::interlocked_read_acquire(&flag.status) + !=ctx.function_complete_flag_value) + { + if(detail::enter_once_region(flag, ctx)) + { + BOOST_TRY + { + BOOST_THREAD_INVOKE_RET_VOID( + thread_detail::decay_copy(boost::forward<Function>(f)), + thread_detail::decay_copy(boost::forward<T1>(p1)), + thread_detail::decay_copy(boost::forward<T2>(p2)), + thread_detail::decay_copy(boost::forward<T3>(p3)) + ) BOOST_THREAD_INVOKE_RET_VOID_CALL; + + } + BOOST_CATCH(...) + { + detail::rollback_once_region(flag, ctx); + BOOST_RETHROW + } + BOOST_CATCH_END + detail::commit_once_region(flag, ctx); + break; + } + if(!ctx.counted) + { + BOOST_INTERLOCKED_INCREMENT(&flag.count); + ctx.counted=true; + long status=::boost::detail::interlocked_read_acquire(&flag.status); + if(status==ctx.function_complete_flag_value) + { + break; + } + if(!ctx.event_handle) + { + ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag); + continue; + } + } + BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject( + ctx.event_handle,::boost::detail::win32::infinite)); + } + } + +#endif +#endif } diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp index 5144e77..1f0f7f5 100644 --- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp @@ -13,5 +13,8 @@ #include <boost/thread/win32/basic_recursive_mutex.hpp> #include <boost/thread/exceptions.hpp> -#include <boost/thread/locks.hpp> +#include <boost/thread/detail/delete.hpp> +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS +#include <boost/thread/lock_types.hpp> +#endif #include <boost/config/abi_prefix.hpp> @@ -33,6 +36,8 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS typedef unique_lock<recursive_mutex> scoped_lock; typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; +#endif }; @@ -53,7 +58,9 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_NESTED_LOCKS typedef unique_lock<recursive_timed_mutex> scoped_timed_lock; typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock; typedef scoped_timed_lock scoped_lock; +#endif }; } diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp index fef2d5b..252174f 100644 --- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp @@ -96,5 +96,5 @@ namespace boost boost::throw_exception(thread_resource_error()); } - state_data state_={0}; + state_data state_={0,0,0,0,0,0}; state=state_; } @@ -134,7 +134,12 @@ namespace boost 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) @@ -142,5 +147,4 @@ namespace boost return timed_lock_shared(get_system_time()+relative_time); } - bool timed_lock_shared(boost::system_time const& wait_until) { @@ -221,4 +225,5 @@ namespace boost } } +#endif #ifdef BOOST_THREAD_USES_CHRONO @@ -379,7 +384,12 @@ namespace boost 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) @@ -387,4 +397,5 @@ namespace boost return timed_lock(get_system_time()+relative_time); } +#endif bool try_lock() @@ -414,4 +425,5 @@ namespace boost +#if defined BOOST_THREAD_USES_DATETIME bool timed_lock(boost::system_time const& wait_until) { @@ -460,4 +472,5 @@ namespace boost for(;;) { + bool must_notify = false; state_data new_state=old_state; if(new_state.shared_count || new_state.exclusive) @@ -468,4 +481,5 @@ namespace boost { new_state.exclusive_waiting_blocked=false; + must_notify = true; } } @@ -477,4 +491,9 @@ namespace boost 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) { @@ -492,5 +511,5 @@ namespace boost } } - +#endif #ifdef BOOST_THREAD_USES_CHRONO template <class Rep, class Period> @@ -569,4 +588,5 @@ namespace boost for(;;) { + bool must_notify = false; state_data new_state=old_state; if(new_state.shared_count || new_state.exclusive) @@ -577,4 +597,5 @@ namespace boost { new_state.exclusive_waiting_blocked=false; + must_notify = true; } } @@ -586,4 +607,8 @@ namespace boost 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) { @@ -725,7 +750,9 @@ namespace boost { release_waiters(old_state); - } else { - release_waiters(old_state); } + // #7720 + //else { + // release_waiters(old_state); + //} break; } diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp index 18fd7cb..1d4f572 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp @@ -23,4 +23,9 @@ #include <boost/config/abi_prefix.hpp> +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4251) +#endif + namespace boost { @@ -68,4 +73,5 @@ namespace boost namespace detail { + struct shared_state_base; struct tss_cleanup_function; struct thread_exit_callback_node; @@ -89,8 +95,6 @@ namespace boost long count; detail::win32::handle_manager thread_handle; - detail::win32::handle_manager interruption_handle; boost::detail::thread_exit_callback_node* thread_exit_callbacks; std::map<void const*,boost::detail::tss_data_node> tss_data; - bool interruption_enabled; unsigned id; typedef std::vector<std::pair<condition_variable*, mutex*> @@ -99,12 +103,24 @@ namespace boost notify_list_t notify; + typedef std::vector<shared_ptr<shared_state_base> > async_states_t; + async_states_t async_states_; +//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + // These data must be at the end so that the access to the other fields doesn't change + // when BOOST_THREAD_PROVIDES_INTERRUPTIONS is defined + // Another option is to have them always + detail::win32::handle_manager interruption_handle; + bool interruption_enabled; +//#endif thread_data_base(): count(0),thread_handle(detail::win32::invalid_handle_value), - interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)), thread_exit_callbacks(0),tss_data(), - interruption_enabled(true), id(0), - notify() + notify(), + async_states_() +//#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS + , interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)) + , interruption_enabled(true) +//#endif {} virtual ~thread_data_base(); @@ -123,19 +139,26 @@ namespace boost } +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void interrupt() { BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0); } - +#endif typedef detail::win32::handle native_handle_type; virtual void run()=0; - void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + virtual void notify_all_at_thread_exit(condition_variable* cv, mutex* m) { notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); } + void make_ready_at_thread_exit(shared_ptr<shared_state_base> as) + { + async_states_.push_back(as); + } + }; + BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr; @@ -143,5 +166,5 @@ namespace boost struct BOOST_SYMBOL_VISIBLE timeout { - unsigned long start; + win32::ticks_type start; uintmax_t milliseconds; bool relative; @@ -151,5 +174,5 @@ namespace boost timeout(uintmax_t milliseconds_): - start(win32::GetTickCount()), + start(win32::GetTickCount64()()), milliseconds(milliseconds_), relative(true), @@ -158,5 +181,5 @@ namespace boost timeout(boost::system_time const& abs_time_): - start(win32::GetTickCount()), + start(win32::GetTickCount64()()), milliseconds(0), relative(false), @@ -183,6 +206,6 @@ namespace boost else if(relative) { - unsigned long const now=win32::GetTickCount(); - unsigned long const elapsed=now-start; + win32::ticks_type const now=win32::GetTickCount64()(); + win32::ticks_type const elapsed=now-start; return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0); } @@ -236,5 +259,4 @@ namespace boost interruptible_wait(detail::win32::invalid_handle_value,abs_time); } - template<typename TimeDuration> inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) @@ -252,8 +274,39 @@ namespace boost } #endif + namespace no_interruption_point + { + bool BOOST_THREAD_DECL non_interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time); + inline void non_interruptible_wait(uintmax_t milliseconds) + { + non_interruptible_wait(detail::win32::invalid_handle_value,milliseconds); + } + inline BOOST_SYMBOL_VISIBLE void non_interruptible_wait(system_time const& abs_time) + { + non_interruptible_wait(detail::win32::invalid_handle_value,abs_time); + } + template<typename TimeDuration> + inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) + { + non_interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds())); + } + inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time) + { + non_interruptible_wait(abs_time); + } +#ifdef BOOST_THREAD_USES_CHRONO + inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) + { + non_interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count()); + } +#endif + } } } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + #include <boost/config/abi_suffix.hpp> 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 9b6d390..610fe32 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp @@ -6,8 +6,10 @@ #define THREAD_HEAP_ALLOC_HPP #include <new> +#include <boost/thread/detail/config.hpp> #include <boost/thread/win32/thread_primitives.hpp> #include <stdexcept> #include <boost/assert.hpp> #include <boost/throw_exception.hpp> +#include <boost/core/no_exceptions_support.hpp> #if defined( BOOST_USE_WINDOWS_H ) @@ -76,18 +78,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } @@ -97,18 +96,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(static_cast<A1&&>(a1)); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } template<typename T,typename A1,typename A2> @@ -116,18 +112,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2)); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } template<typename T,typename A1,typename A2,typename A3> @@ -135,7 +128,5 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), @@ -143,11 +134,10 @@ namespace boost return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } template<typename T,typename A1,typename A2,typename A3,typename A4> @@ -155,7 +145,5 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), @@ -163,11 +151,10 @@ namespace boost return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } #else @@ -176,18 +163,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(a1); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } @@ -196,18 +180,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(a1,a2); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } @@ -216,18 +197,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(a1,a2,a3); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } @@ -236,18 +214,15 @@ namespace boost { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -#ifndef BOOST_NO_EXCEPTIONS - try // BOOST_NO_EXCEPTIONS protected -#endif + BOOST_TRY { T* const data=new (heap_memory) T(a1,a2,a3,a4); return data; } -#ifndef BOOST_NO_EXCEPTIONS - catch(...) // BOOST_NO_EXCEPTIONS protected + BOOST_CATCH(...) { free_raw_heap_memory(heap_memory); - throw; // BOOST_NO_EXCEPTIONS protected + BOOST_RETHROW } -#endif + BOOST_CATCH_END } diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp index c0dba11..fcf59b3 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -16,4 +16,5 @@ #include <boost/thread/exceptions.hpp> #include <boost/detail/interlocked.hpp> +//#include <boost/detail/winapi/synchronization.hpp> #include <algorithm> @@ -27,5 +28,4 @@ namespace boost namespace win32 { - typedef ULONG_PTR ulong_ptr; typedef HANDLE handle; unsigned const infinite=INFINITE; @@ -34,4 +34,6 @@ namespace boost unsigned const event_modify_state=EVENT_MODIFY_STATE; unsigned const synchronize=SYNCHRONIZE; + unsigned const wait_abandoned=WAIT_ABANDONED; + # ifdef BOOST_NO_ANSI_APIS @@ -61,5 +63,4 @@ namespace boost using ::Sleep; using ::QueueUserAPC; - using ::GetTickCount; } } @@ -89,4 +90,5 @@ typedef void* HANDLE; # endif + namespace boost { @@ -95,5 +97,4 @@ namespace boost namespace win32 { - # ifdef _WIN64 typedef unsigned __int64 ulong_ptr; @@ -107,4 +108,5 @@ namespace boost unsigned const event_modify_state=2; unsigned const synchronize=0x100000u; + unsigned const wait_abandoned=0x00000080u; extern "C" @@ -133,6 +135,4 @@ namespace boost __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr); - __declspec(dllimport) unsigned long __stdcall GetTickCount(); - # ifndef UNDER_CE __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); @@ -166,5 +166,86 @@ namespace boost namespace win32 { - enum event_type + typedef unsigned __int64 ticks_type; + namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); } + extern "C" + { + __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *); +#if !defined(BOOST_NO_ANSI_APIS) + __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *); +#else + __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *); +#endif + int __stdcall GetTickCount(); + long _InterlockedCompareExchange(long volatile *, long, long); +#pragma intrinsic(_InterlockedCompareExchange) + } + // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar + inline ticks_type __stdcall GetTickCount64emulation() + { + static volatile long count = 0xFFFFFFFF; + unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone; + ticks_type current_tick64; + + previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0); + current_tick32 = GetTickCount(); + + if(previous_count == 0xFFFFFFFF) + { + // count has never been written + unsigned long initial_count; + initial_count = current_tick32 >> 28; + previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF); + + current_tick64 = initial_count; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + previous_count_zone = previous_count & 15; + current_tick32_zone = current_tick32 >> 28; + + if(current_tick32_zone == previous_count_zone) + { + // The top four bits of the 32-bit tick count haven't changed since count was last written. + current_tick64 = previous_count; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15)) + { + // The top four bits of the 32-bit tick count have been incremented since count was last written. + _InterlockedCompareExchange(&count, previous_count + 1, previous_count); + current_tick64 = previous_count + 1; + current_tick64 <<= 28; + current_tick64 += current_tick32 & 0x0FFFFFFF; + return current_tick64; + } + + // Oops, we weren't called often enough, we're stuck + return 0xFFFFFFFF; + } + inline detail::gettickcount64_t GetTickCount64() + { + static detail::gettickcount64_t gettickcount64impl; + if(gettickcount64impl) + return gettickcount64impl; + detail::farproc_t addr=GetProcAddress( +#if !defined(BOOST_NO_ANSI_APIS) + GetModuleHandleA("KERNEL32.DLL"), +#else + GetModuleHandleW(L"KERNEL32.DLL"), +#endif + "GetTickCount64"); + if(addr) + gettickcount64impl=(detail::gettickcount64_t) addr; + else + gettickcount64impl=&GetTickCount64emulation; + return gettickcount64impl; + } + + enum event_type { auto_reset_event=false, @@ -233,5 +314,5 @@ namespace boost } - class handle_manager + class BOOST_THREAD_DECL handle_manager { private: |
Swift