diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
11 files changed, 872 insertions, 239 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 05eb8d7..e259121 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp @@ -3,14 +3,19 @@ // basic_recursive_mutex.hpp // -// (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include "thread_primitives.hpp" -#include "basic_timed_mutex.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/basic_timed_mutex.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif #include <boost/config/abi_prefix.hpp> @@ -37,12 +42,12 @@ namespace boost mutex.destroy(); } - bool try_lock() + bool try_lock() BOOST_NOEXCEPT { long const current_thread_id=win32::GetCurrentThreadId(); return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); } - + void lock() { long const current_thread_id=win32::GetCurrentThreadId(); @@ -64,6 +69,20 @@ namespace boost return timed_lock(get_system_time()+timeout); } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time); + } + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& t) + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t); + } +#endif void unlock() { if(!--recursion_count) @@ -74,7 +93,7 @@ namespace boost } private: - bool try_recursive_lock(long current_thread_id) + bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT { if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) { @@ -83,8 +102,8 @@ namespace boost } return false; } - - bool try_basic_lock(long current_thread_id) + + bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT { if(mutex.try_lock()) { @@ -94,7 +113,7 @@ namespace boost } return false; } - + bool try_timed_lock(long current_thread_id,::boost::system_time const& target) { if(mutex.timed_lock(target)) @@ -105,7 +124,28 @@ namespace boost } return false; } - + template <typename TP> + bool try_timed_lock_until(long current_thread_id,TP const& target) + { + if(mutex.try_lock_until(target)) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } + template <typename D> + bool try_timed_lock_for(long current_thread_id,D const& target) + { + if(mutex.try_lock_for(target)) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } }; typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex; 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 7c6797d..6a43077 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp @@ -3,19 +3,23 @@ // basic_timed_mutex_win32.hpp // -// (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <boost/assert.hpp> -#include "thread_primitives.hpp" -#include "interlocked_read.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/interlocked_read.hpp> #include <boost/thread/thread_time.hpp> #include <boost/thread/xtime.hpp> #include <boost/detail/interlocked.hpp> - +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif #include <boost/config/abi_prefix.hpp> namespace boost @@ -52,13 +56,13 @@ namespace boost win32::CloseHandle(old_event); } } - - - bool try_lock() + + + bool try_lock() BOOST_NOEXCEPT { return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit); } - + void lock() { if(try_lock()) @@ -112,8 +116,8 @@ namespace boost old_count=current; } } - - + + bool timed_lock(::boost::system_time const& wait_until) { if(try_lock()) @@ -143,6 +147,7 @@ namespace boost return true; } + template<typename Duration> bool timed_lock(Duration const& timeout) { @@ -154,6 +159,59 @@ namespace boost return timed_lock(system_time(timeout)); } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + system_clock::time_point s_now = system_clock::now(); + typename Clock::time_point c_now = Clock::now(); + return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now)); + } + template <class Duration> + bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) + { + using namespace chrono; + typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; + return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); + } + bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) + { + if(try_lock()) + { + return true; + } + 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 + { + chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); + + if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0) + { + BOOST_INTERLOCKED_DECREMENT(&active_count); + return false; + } + clear_waiting_and_try_lock(old_count); + lock_acquired=!(old_count&lock_flag_value); + } + while(!lock_acquired); + } + return true; + } +#endif + void unlock() { long const offset=lock_flag_value; @@ -171,7 +229,7 @@ namespace boost void* get_event() { void* current_event=::boost::detail::interlocked_read_acquire(&event); - + if(!current_event) { void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset); @@ -196,9 +254,9 @@ namespace boost } return current_event; } - + }; - + } } diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp index 6e676b4..4c893ad 100644 --- a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp @@ -4,18 +4,28 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/thread_data.hpp> +#include <boost/thread/win32/thread_data.hpp> +#include <boost/thread/win32/interlocked_read.hpp> +#include <boost/thread/cv_status.hpp> +#include <boost/thread/xtime.hpp> #include <boost/thread/mutex.hpp> -#include "thread_primitives.hpp" -#include <limits.h> +#include <boost/thread/thread_time.hpp> + #include <boost/assert.hpp> +#include <boost/intrusive_ptr.hpp> + +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif + +#include <limits.h> #include <algorithm> -#include <boost/thread/thread.hpp> -#include <boost/thread/thread_time.hpp> -#include "interlocked_read.hpp" -#include <boost/thread/xtime.hpp> #include <vector> -#include <boost/intrusive_ptr.hpp> #include <boost/config/abi_prefix.hpp> @@ -26,7 +36,7 @@ namespace boost class basic_cv_list_entry; void intrusive_ptr_add_ref(basic_cv_list_entry * p); void intrusive_ptr_release(basic_cv_list_entry * p); - + class basic_cv_list_entry { private: @@ -36,10 +46,8 @@ namespace boost bool notified; long references; - basic_cv_list_entry(basic_cv_list_entry&); - void operator=(basic_cv_list_entry&); - public: + BOOST_THREAD_NO_COPYABLE(basic_cv_list_entry) explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_): semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)), wake_sem(wake_sem_.duplicate()), @@ -55,7 +63,7 @@ namespace boost { BOOST_INTERLOCKED_INCREMENT(&waiters); } - + void remove_waiter() { BOOST_INTERLOCKED_DECREMENT(&waiters); @@ -77,9 +85,9 @@ namespace boost return notified; } - bool wait(timeout wait_until) + bool wait(timeout abs_time) { - return this_thread::interruptible_wait(semaphore,wait_until); + return this_thread::interruptible_wait(semaphore,abs_time); } bool woken() @@ -97,7 +105,7 @@ namespace boost { BOOST_INTERLOCKED_INCREMENT(&p->references); } - + inline void intrusive_ptr_release(basic_cv_list_entry * p) { if(!BOOST_INTERLOCKED_DECREMENT(&p->references)) @@ -125,13 +133,14 @@ namespace boost detail::interlocked_write_release(&total_count,total_count-count_to_wake); detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0); } - + template<typename lock_type> struct relocker { + BOOST_THREAD_NO_COPYABLE(relocker) lock_type& lock; bool unlocked; - + relocker(lock_type& lock_): lock(lock_),unlocked(false) {} @@ -146,13 +155,10 @@ namespace boost { lock.lock(); } - + } - private: - relocker(relocker&); - void operator=(relocker&); }; - + entry_ptr get_wait_entry() { @@ -177,37 +183,37 @@ namespace boost return generations.back(); } } - + struct entry_manager { entry_ptr const entry; - + + BOOST_THREAD_NO_COPYABLE(entry_manager) entry_manager(entry_ptr const& entry_): entry(entry_) {} - + ~entry_manager() { + if(! entry->is_notified()) + { entry->remove_waiter(); + } } list_entry* operator->() { return entry.get(); } - - private: - void operator=(entry_manager&); - entry_manager(entry_manager&); }; - + protected: template<typename lock_type> - bool do_wait(lock_type& lock,timeout wait_until) + bool do_wait(lock_type& lock,timeout abs_time) { relocker<lock_type> locker(lock); - + entry_manager entry(get_wait_entry()); locker.unlock(); @@ -215,27 +221,27 @@ namespace boost bool woken=false; while(!woken) { - if(!entry->wait(wait_until)) + if(!entry->wait(abs_time)) { return false; } - + woken=entry->woken(); } return woken; } template<typename lock_type,typename predicate_type> - bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred) + bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred) { while (!pred()) { - if(!do_wait(m, wait_until)) + if(!do_wait(m, abs_time)) return pred(); } return true; } - + basic_condition_variable(const basic_condition_variable& other); basic_condition_variable& operator=(const basic_condition_variable& other); @@ -243,11 +249,11 @@ namespace boost basic_condition_variable(): total_count(0),active_generation_count(0),wake_sem(0) {} - + ~basic_condition_variable() {} - void notify_one() + void notify_one() BOOST_NOEXCEPT { if(detail::interlocked_read_acquire(&total_count)) { @@ -267,8 +273,8 @@ namespace boost generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end()); } } - - void notify_all() + + void notify_all() BOOST_NOEXCEPT { if(detail::interlocked_read_acquire(&total_count)) { @@ -288,23 +294,21 @@ namespace boost wake_sem=detail::win32::handle(0); } } - + }; } class condition_variable: private detail::basic_condition_variable { - private: - condition_variable(condition_variable&); - void operator=(condition_variable&); public: + BOOST_THREAD_NO_COPYABLE(condition_variable) condition_variable() {} - + using detail::basic_condition_variable::notify_one; using detail::basic_condition_variable::notify_all; - + void wait(unique_lock<mutex>& m) { do_wait(m,detail::timeout::sentinel()); @@ -315,16 +319,16 @@ namespace boost { while(!pred()) wait(m); } - - bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) + + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time) { - return do_wait(m,wait_until); + return do_wait(m,abs_time); } - bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until) + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time) { - return do_wait(m,system_time(wait_until)); + return do_wait(m,system_time(abs_time)); } template<typename duration_type> bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) @@ -333,35 +337,85 @@ namespace boost } template<typename predicate_type> - bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred) { - return do_wait(m,wait_until,pred); + return do_wait(m,abs_time,pred); } template<typename predicate_type> - bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred) + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred) { - return do_wait(m,system_time(wait_until),pred); + return do_wait(m,system_time(abs_time),pred); } template<typename duration_type,typename predicate_type> bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) { return do_wait(m,wait_duration.total_milliseconds(),pred); } + +#ifdef BOOST_THREAD_USES_CHRONO + + template <class Clock, class Duration> + cv_status + wait_until( + unique_lock<mutex>& lock, + const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); + return Clock::now() < t ? cv_status::no_timeout : + cv_status::timeout; + } + + template <class Rep, class Period> + cv_status + wait_for( + unique_lock<mutex>& lock, + const chrono::duration<Rep, Period>& d) + { + using namespace chrono; + steady_clock::time_point c_now = steady_clock::now(); + do_wait(lock, ceil<milliseconds>(d).count()); + return steady_clock::now() - c_now < d ? cv_status::no_timeout : + cv_status::timeout; + } + + template <class Clock, class Duration, class Predicate> + bool + wait_until( + unique_lock<mutex>& lock, + const chrono::time_point<Clock, Duration>& t, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, t) == cv_status::timeout) + return pred(); + } + return true; + } + template <class Rep, class Period, class Predicate> + bool + wait_for( + unique_lock<mutex>& lock, + const chrono::duration<Rep, Period>& d, + Predicate pred) + { + return wait_until(lock, chrono::steady_clock::now() + d, pred); + } +#endif }; - + class condition_variable_any: private detail::basic_condition_variable { - private: - condition_variable_any(condition_variable_any&); - void operator=(condition_variable_any&); public: + BOOST_THREAD_NO_COPYABLE(condition_variable_any) condition_variable_any() {} - + using detail::basic_condition_variable::notify_one; using detail::basic_condition_variable::notify_all; - + template<typename lock_type> void wait(lock_type& m) { @@ -373,17 +427,17 @@ namespace boost { while(!pred()) wait(m); } - + template<typename lock_type> - bool timed_wait(lock_type& m,boost::system_time const& wait_until) + bool timed_wait(lock_type& m,boost::system_time const& abs_time) { - return do_wait(m,wait_until); + return do_wait(m,abs_time); } template<typename lock_type> - bool timed_wait(lock_type& m,boost::xtime const& wait_until) + bool timed_wait(lock_type& m,boost::xtime const& abs_time) { - return do_wait(m,system_time(wait_until)); + return do_wait(m,system_time(abs_time)); } template<typename lock_type,typename duration_type> @@ -393,15 +447,15 @@ namespace boost } template<typename lock_type,typename predicate_type> - bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred) { - return do_wait(m,wait_until,pred); + return do_wait(m,abs_time,pred); } template<typename lock_type,typename predicate_type> - bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred) + bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred) { - return do_wait(m,system_time(wait_until),pred); + return do_wait(m,system_time(abs_time),pred); } template<typename lock_type,typename duration_type,typename predicate_type> @@ -409,8 +463,61 @@ namespace boost { return do_wait(m,wait_duration.total_milliseconds(),pred); } +#ifdef BOOST_THREAD_USES_CHRONO + + template <class lock_type, class Clock, class Duration> + cv_status + wait_until( + lock_type& lock, + const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); + return Clock::now() < t ? cv_status::no_timeout : + cv_status::timeout; + } + + template <class lock_type, class Rep, class Period> + cv_status + wait_for( + lock_type& lock, + const chrono::duration<Rep, Period>& d) + { + using namespace chrono; + steady_clock::time_point c_now = steady_clock::now(); + do_wait(lock, ceil<milliseconds>(d).count()); + return steady_clock::now() - c_now < d ? cv_status::no_timeout : + cv_status::timeout; + } + + template <class lock_type, class Clock, class Duration, class Predicate> + bool + wait_until( + lock_type& lock, + const chrono::time_point<Clock, Duration>& t, + Predicate pred) + { + while (!pred()) + { + if (wait_until(lock, t) == cv_status::timeout) + return pred(); + } + return true; + } + + template <class lock_type, class Rep, class Period, class Predicate> + bool + wait_for( + lock_type& lock, + const chrono::duration<Rep, Period>& d, + Predicate pred) + { + return wait_until(lock, chrono::steady_clock::now() + d, pred); + } +#endif }; + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk); } #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp index 133fb6f..4a96998 100644 --- a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp @@ -3,13 +3,15 @@ // interlocked_read_win32.hpp // -// (C) Copyright 2005-8 Anthony Williams +// (C) Copyright 2005-8 Anthony Williams +// (C) Copyright 2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include <boost/detail/interlocked.hpp> +#include <boost/thread/detail/config.hpp> #include <boost/config/abi_prefix.hpp> @@ -22,25 +24,25 @@ namespace boost { namespace detail { - inline long interlocked_read_acquire(long volatile* x) + inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT { long const res=*x; _ReadWriteBarrier(); return res; } - inline void* interlocked_read_acquire(void* volatile* x) + inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT { void* const res=*x; _ReadWriteBarrier(); return res; } - inline void interlocked_write_release(long volatile* x,long value) + inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT { _ReadWriteBarrier(); *x=value; } - inline void interlocked_write_release(void* volatile* x,void* value) + inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT { _ReadWriteBarrier(); *x=value; @@ -54,19 +56,19 @@ namespace boost { namespace detail { - inline long interlocked_read_acquire(long volatile* x) + inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT { return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0); } - inline void* interlocked_read_acquire(void* volatile* x) + inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT { return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0); } - inline void interlocked_write_release(long volatile* x,long value) + inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT { BOOST_INTERLOCKED_EXCHANGE(x,value); } - inline void interlocked_write_release(void* volatile* x,void* value) + inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT { BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value); } diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp index d59fbfa..85a00e2 100644 --- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp @@ -1,12 +1,12 @@ #ifndef BOOST_THREAD_WIN32_MUTEX_HPP #define BOOST_THREAD_WIN32_MUTEX_HPP // (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include "basic_timed_mutex.hpp" -#include <boost/utility.hpp> +#include <boost/thread/win32/basic_timed_mutex.hpp> #include <boost/thread/exceptions.hpp> #include <boost/thread/locks.hpp> @@ -22,10 +22,8 @@ namespace boost class mutex: public ::boost::detail::underlying_mutex { - private: - mutex(mutex const&); - mutex& operator=(mutex const&); public: + BOOST_THREAD_NO_COPYABLE(mutex) mutex() { initialize(); @@ -44,10 +42,8 @@ namespace boost class timed_mutex: public ::boost::detail::basic_timed_mutex { - private: - timed_mutex(timed_mutex const&); - timed_mutex& operator=(timed_mutex const&); public: + BOOST_THREAD_NO_COPYABLE(timed_mutex) timed_mutex() { initialize(); diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp index e1b1843..3066b50 100644 --- a/3rdParty/Boost/src/boost/thread/win32/once.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -3,8 +3,9 @@ // once.hpp // -// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2005-7 Anthony Williams // (C) Copyright 2005 John Maddock +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -30,6 +31,25 @@ namespace std namespace boost { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + + struct once_flag + { + BOOST_THREAD_NO_COPYABLE(once_flag) + BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT + : status(0), count(0) + {} + private: + long status; + long count; + template<typename Function> + friend + void call_once(once_flag& flag,Function f); + }; + +#define BOOST_ONCE_INIT once_flag() +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 + struct once_flag { long status; @@ -37,6 +57,7 @@ namespace boost }; #define BOOST_ONCE_INIT {0,0} +#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 namespace detail { @@ -71,29 +92,29 @@ namespace boost #else static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; #endif - BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == + BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) == (sizeof(once_char_type)*(once_mutex_name_fixed_length+1))); - + std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); - detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), + detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length); - detail::int_to_string(win32::GetCurrentProcessId(), + detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); } - + inline void* open_once_event(once_char_type* mutex_name,void* flag_address) { if(!*mutex_name) { name_once_mutex(mutex_name,flag_address); } - -#ifdef BOOST_NO_ANSI_APIS + +#ifdef BOOST_NO_ANSI_APIS return ::boost::detail::win32::OpenEventW( #else return ::boost::detail::win32::OpenEventA( #endif - ::boost::detail::win32::synchronize | + ::boost::detail::win32::synchronize | ::boost::detail::win32::event_modify_state, false, mutex_name); @@ -105,7 +126,7 @@ namespace boost { name_once_mutex(mutex_name,flag_address); } -#ifdef BOOST_NO_ANSI_APIS +#ifdef BOOST_NO_ANSI_APIS return ::boost::detail::win32::CreateEventW( #else return ::boost::detail::win32::CreateEventA( @@ -115,7 +136,7 @@ namespace boost mutex_name); } } - + template<typename Function> void call_once(once_flag& flag,Function f) @@ -136,7 +157,9 @@ namespace boost status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0); if(!status) { - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { if(!event_handle) { @@ -153,7 +176,7 @@ namespace boost counted=true; } BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value); - if(!event_handle && + if(!event_handle && (::boost::detail::interlocked_read_acquire(&flag.count)>1)) { event_handle=detail::create_once_event(mutex_name,&flag); @@ -164,7 +187,8 @@ namespace boost } break; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { BOOST_INTERLOCKED_EXCHANGE(&flag.status,0); if(!event_handle) @@ -175,8 +199,9 @@ namespace boost { ::boost::detail::win32::SetEvent(event_handle); } - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } if(!counted) diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp index e83d3bc..5144e77 100644 --- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp @@ -3,15 +3,14 @@ // recursive_mutex.hpp // -// (C) Copyright 2006-7 Anthony Williams +// (C) Copyright 2006-7 Anthony Williams // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include <boost/utility.hpp> -#include "basic_recursive_mutex.hpp" +#include <boost/thread/win32/basic_recursive_mutex.hpp> #include <boost/thread/exceptions.hpp> #include <boost/thread/locks.hpp> @@ -22,10 +21,8 @@ namespace boost class recursive_mutex: public ::boost::detail::basic_recursive_mutex { - private: - recursive_mutex(recursive_mutex const&); - recursive_mutex& operator=(recursive_mutex const&); public: + BOOST_THREAD_NO_COPYABLE(recursive_mutex) recursive_mutex() { ::boost::detail::basic_recursive_mutex::initialize(); @@ -44,10 +41,8 @@ namespace boost class recursive_timed_mutex: public ::boost::detail::basic_recursive_timed_mutex { - private: - recursive_timed_mutex(recursive_timed_mutex const&); - recursive_timed_mutex& operator=(recursive_timed_mutex const&); public: + BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex) recursive_timed_mutex() { ::boost::detail::basic_recursive_timed_mutex::initialize(); diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp index 58fc622..fef2d5b 100644 --- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp @@ -2,6 +2,7 @@ #define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP // (C) Copyright 2006-8 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at @@ -12,8 +13,12 @@ #include <boost/thread/win32/thread_primitives.hpp> #include <boost/static_assert.hpp> #include <limits.h> -#include <boost/utility.hpp> #include <boost/thread/thread_time.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp> #include <boost/config/abi_prefix.hpp> @@ -22,9 +27,6 @@ namespace boost class shared_mutex { private: - shared_mutex(shared_mutex const&); - shared_mutex& operator=(shared_mutex const&); - private: struct state_data { unsigned shared_count:11, @@ -39,7 +41,7 @@ namespace boost return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs); } }; - + template<typename T> T interlocked_compare_exchange(T* target,T new_value,T comparand) @@ -67,20 +69,32 @@ namespace boost { BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0); } - + if(old_state.shared_waiting || old_state.exclusive_waiting) { BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); } } - + public: + BOOST_THREAD_NO_COPYABLE(shared_mutex) shared_mutex() { semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); - semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); - upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); + if (!semaphores[exclusive_sem]) + { + detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); + boost::throw_exception(thread_resource_error()); + } + upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); + if (!upgrade_sem) + { + detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); + detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX); + boost::throw_exception(thread_resource_error()); + } state_data state_={0}; state=state_; } @@ -106,7 +120,7 @@ namespace boost return false; } } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { @@ -165,7 +179,7 @@ namespace boost { return true; } - + unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until)); if(res==detail::win32::timeout) { @@ -202,11 +216,120 @@ namespace boost } return false; } - + BOOST_ASSERT(res==0); } } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_shared_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + system_clock::time_point s_now = system_clock::now(); + typename Clock::time_point c_now = Clock::now(); + return try_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now)); + } + template <class Duration> + bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t) + { + using namespace chrono; + typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; + return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); + } + bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) + { + for(;;) + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + ++new_state.shared_waiting; + if(!new_state.shared_waiting) + { + boost::throw_exception(boost::lock_error()); + } + } + else + { + ++new_state.shared_count; + if(!new_state.shared_count) + { + boost::throw_exception(boost::lock_error()); + } + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + + chrono::system_clock::time_point n = chrono::system_clock::now(); + unsigned long res; + if (tp>n) { + chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n); + res=detail::win32::WaitForSingleObject(semaphores[unlock_sem], + static_cast<unsigned long>(rel_time.count())); + } else { + res=detail::win32::timeout; + } + if(res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + if(new_state.shared_waiting) + { + --new_state.shared_waiting; + } + } + else + { + ++new_state.shared_count; + if(!new_state.shared_count) + { + return false; + } + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + return false; + } + + BOOST_ASSERT(res==0); + } + } +#endif + void unlock_shared() { state_data old_state=state; @@ -214,7 +337,7 @@ namespace boost { state_data new_state=old_state; bool const last_reader=!--new_state.shared_count; - + if(last_reader) { if(new_state.upgrade) @@ -232,7 +355,7 @@ namespace boost new_state.shared_waiting=0; } } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { @@ -278,7 +401,7 @@ namespace boost { new_state.exclusive=true; } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { @@ -306,7 +429,7 @@ namespace boost { boost::throw_exception(boost::lock_error()); } - + new_state.exclusive_waiting_blocked=true; } else @@ -326,7 +449,12 @@ namespace boost { return true; } - unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until)); + #ifndef UNDER_CE + const bool wait_all = true; + #else + const bool wait_all = false; + #endif + unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until)); if(wait_res==detail::win32::timeout) { for(;;) @@ -364,6 +492,116 @@ namespace boost } } +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_lock_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_lock_until(const chrono::time_point<Clock, Duration>& t) + { + using namespace chrono; + system_clock::time_point s_now = system_clock::now(); + typename Clock::time_point c_now = Clock::now(); + return try_lock_until(s_now + ceil<system_clock::duration>(t - c_now)); + } + template <class Duration> + bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) + { + using namespace chrono; + typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; + return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); + } + bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) + { + for(;;) + { + state_data old_state=state; + + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + ++new_state.exclusive_waiting; + if(!new_state.exclusive_waiting) + { + boost::throw_exception(boost::lock_error()); + } + + new_state.exclusive_waiting_blocked=true; + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + #ifndef UNDER_CE + const bool wait_all = true; + #else + const bool wait_all = false; + #endif + + chrono::system_clock::time_point n = chrono::system_clock::now(); + unsigned long wait_res; + if (tp>n) { + chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); + wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all, + static_cast<unsigned long>(rel_time.count())); + } else { + wait_res=detail::win32::timeout; + } + if(wait_res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + if(new_state.exclusive_waiting) + { + if(!--new_state.exclusive_waiting) + { + new_state.exclusive_waiting_blocked=false; + } + } + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + return false; + } + BOOST_ASSERT(wait_res<2); + } + } +#endif + void unlock() { state_data old_state=state; @@ -426,7 +664,7 @@ namespace boost { return; } - + BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite)); } } @@ -450,7 +688,7 @@ namespace boost } new_state.upgrade=true; } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { @@ -469,7 +707,7 @@ namespace boost state_data new_state=old_state; new_state.upgrade=false; bool const last_reader=!--new_state.shared_count; - + if(last_reader) { if(new_state.exclusive_waiting) @@ -479,13 +717,15 @@ namespace boost } new_state.shared_waiting=0; } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { if(last_reader) { release_waiters(old_state); + } else { + release_waiters(old_state); } break; } @@ -500,13 +740,13 @@ namespace boost { state_data new_state=old_state; bool const last_reader=!--new_state.shared_count; - + if(last_reader) { new_state.upgrade=false; new_state.exclusive=true; } - + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); if(current_state==old_state) { @@ -545,7 +785,28 @@ namespace boost } release_waiters(old_state); } - +// bool try_unlock_upgrade_and_lock() +// { +// return false; +// } +//#ifdef BOOST_THREAD_USES_CHRONO +// template <class Rep, class Period> +// bool +// try_unlock_upgrade_and_lock_for( +// const chrono::duration<Rep, Period>& rel_time) +// { +// return try_unlock_upgrade_and_lock_until( +// chrono::steady_clock::now() + rel_time); +// } +// template <class Clock, class Duration> +// bool +// try_unlock_upgrade_and_lock_until( +// const chrono::time_point<Clock, Duration>& abs_time) +// { +// return false; +// } +//#endif + void unlock_and_lock_shared() { state_data old_state=state; @@ -570,7 +831,6 @@ namespace boost } release_waiters(old_state); } - void unlock_upgrade_and_lock_shared() { state_data old_state=state; @@ -594,8 +854,10 @@ namespace boost } release_waiters(old_state); } - + }; + typedef shared_mutex upgrade_mutex; + } #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp index c86b0fa..18fd7cb 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp @@ -4,51 +4,116 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2008 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba #include <boost/thread/detail/config.hpp> -#include <boost/intrusive_ptr.hpp> #include <boost/thread/thread_time.hpp> -#include "thread_primitives.hpp" -#include "thread_heap_alloc.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/thread_heap_alloc.hpp> + +#include <boost/intrusive_ptr.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif + +#include <map> +#include <vector> +#include <utility> #include <boost/config/abi_prefix.hpp> namespace boost { + class condition_variable; + class mutex; + + class thread_attributes { + public: + thread_attributes() BOOST_NOEXCEPT { + val_.stack_size = 0; + //val_.lpThreadAttributes=0; + } + ~thread_attributes() { + } + // stack size + void set_stack_size(std::size_t size) BOOST_NOEXCEPT { + val_.stack_size = size; + } + + std::size_t get_stack_size() const BOOST_NOEXCEPT { + return val_.stack_size; + } + + //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes) + //{ + // val_.lpThreadAttributes=lpThreadAttributes; + //} + //LPSECURITY_ATTRIBUTES get_security() + //{ + // return val_.lpThreadAttributes; + //} + + struct win_attrs { + std::size_t stack_size; + //LPSECURITY_ATTRIBUTES lpThreadAttributes; + }; + typedef win_attrs native_handle_type; + native_handle_type* native_handle() {return &val_;} + const native_handle_type* native_handle() const {return &val_;} + + private: + win_attrs val_; + }; + namespace detail { + struct tss_cleanup_function; struct thread_exit_callback_node; - struct tss_data_node; + struct tss_data_node + { + boost::shared_ptr<boost::detail::tss_cleanup_function> func; + void* value; + + tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, + void* value_): + func(func_),value(value_) + {} + }; struct thread_data_base; void intrusive_ptr_add_ref(thread_data_base * p); void intrusive_ptr_release(thread_data_base * p); - - struct thread_data_base + + struct BOOST_THREAD_DECL thread_data_base { long count; detail::win32::handle_manager thread_handle; detail::win32::handle_manager interruption_handle; boost::detail::thread_exit_callback_node* thread_exit_callbacks; - boost::detail::tss_data_node* tss_data; + std::map<void const*,boost::detail::tss_data_node> tss_data; bool interruption_enabled; unsigned id; + typedef std::vector<std::pair<condition_variable*, mutex*> + //, hidden_allocator<std::pair<condition_variable*, mutex*> > + > notify_list_t; + notify_list_t notify; + 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(0), + thread_exit_callbacks(0),tss_data(), interruption_enabled(true), - id(0) - {} - virtual ~thread_data_base() + id(0), + notify() {} + virtual ~thread_data_base(); friend void intrusive_ptr_add_ref(thread_data_base * p) { BOOST_INTERLOCKED_INCREMENT(&p->count); } - + friend void intrusive_ptr_release(thread_data_base * p) { if(!BOOST_INTERLOCKED_DECREMENT(&p->count)) @@ -61,15 +126,21 @@ namespace boost { BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0); } - + typedef detail::win32::handle native_handle_type; virtual void run()=0; + + void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + { + notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); + } + }; typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr; - struct timeout + struct BOOST_SYMBOL_VISIBLE timeout { unsigned long start; uintmax_t milliseconds; @@ -92,7 +163,7 @@ namespace boost abs_time(abs_time_) {} - struct remaining_time + struct BOOST_SYMBOL_VISIBLE remaining_time { bool more; unsigned long milliseconds; @@ -130,7 +201,7 @@ namespace boost { return milliseconds==~uintmax_t(0); } - + static timeout sentinel() { @@ -139,43 +210,49 @@ namespace boost private: struct sentinel_type {}; - + explicit timeout(sentinel_type): start(0),milliseconds(~uintmax_t(0)),relative(true) {} }; - inline unsigned long pin_to_zero(long value) + inline uintmax_t pin_to_zero(intmax_t value) { - return (value<0)?0u:(unsigned long)value; + return (value<0)?0u:(uintmax_t)value; } } namespace this_thread { - void BOOST_THREAD_DECL yield(); + void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT; bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time); - inline void interruptible_wait(unsigned long milliseconds) + inline void interruptible_wait(uintmax_t milliseconds) { interruptible_wait(detail::win32::invalid_handle_value,milliseconds); } - inline void interruptible_wait(system_time const& abs_time) + inline BOOST_SYMBOL_VISIBLE void interruptible_wait(system_time const& abs_time) { interruptible_wait(detail::win32::invalid_handle_value,abs_time); } template<typename TimeDuration> - inline void sleep(TimeDuration const& rel_time) + inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) { interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds())); } - inline void sleep(system_time const& abs_time) + inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time) { interruptible_wait(abs_time); } +#ifdef BOOST_THREAD_USES_CHRONO + inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) + { + interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count()); + } +#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 c210a91..9b6d390 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp @@ -5,7 +5,7 @@ #ifndef THREAD_HEAP_ALLOC_HPP #define THREAD_HEAP_ALLOC_HPP #include <new> -#include "thread_primitives.hpp" +#include <boost/thread/win32/thread_primitives.hpp> #include <stdexcept> #include <boost/assert.hpp> #include <boost/throw_exception.hpp> @@ -56,7 +56,7 @@ namespace boost { namespace detail { - inline /*BOOST_THREAD_DECL*/ void* allocate_raw_heap_memory(unsigned size) + inline void* allocate_raw_heap_memory(unsigned size) { void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size); if(!heap_memory) @@ -66,153 +66,189 @@ namespace boost return heap_memory; } - inline /*BOOST_THREAD_DECL*/ void free_raw_heap_memory(void* heap_memory) + inline void free_raw_heap_memory(void* heap_memory) { BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0); } - + template<typename T> inline T* heap_new() { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template<typename T,typename A1> inline T* heap_new(A1&& a1) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(static_cast<A1&&>(a1)); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2> inline T* heap_new(A1&& a1,A2&& a2) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2)); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2,typename A3> inline T* heap_new(A1&& a1,A2&& a2,A3&& a3) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), static_cast<A3&&>(a3)); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2,typename A3,typename A4> inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), static_cast<A3&&>(a3),static_cast<A4&&>(a4)); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } #else template<typename T,typename A1> inline T* heap_new_impl(A1 a1) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(a1); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2> inline T* heap_new_impl(A1 a1,A2 a2) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(a1,a2); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2,typename A3> inline T* heap_new_impl(A1 a1,A2 a2,A3 a3) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(a1,a2,a3); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } template<typename T,typename A1,typename A2,typename A3,typename A4> inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4) { void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); - try +#ifndef BOOST_NO_EXCEPTIONS + try // BOOST_NO_EXCEPTIONS protected +#endif { T* const data=new (heap_memory) T(a1,a2,a3,a4); return data; } - catch(...) +#ifndef BOOST_NO_EXCEPTIONS + catch(...) // BOOST_NO_EXCEPTIONS protected { free_raw_heap_memory(heap_memory); - throw; + throw; // BOOST_NO_EXCEPTIONS protected } +#endif } @@ -226,7 +262,7 @@ namespace boost { return heap_new_impl<T,A1&>(a1); } - + template<typename T,typename A1,typename A2> inline T* heap_new(A1 const& a1,A2 const& a2) { @@ -372,8 +408,8 @@ namespace boost { return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4); } - -#endif + +#endif template<typename T> inline void heap_delete(T* data) { diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp index 9b20e86..c0dba11 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -3,14 +3,14 @@ // win32_thread_primitives.hpp // -// (C) Copyright 2005-7 Anthony Williams -// (C) Copyright 2007 David Deakins +// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2007 David Deakins // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#include <boost/config.hpp> +#include <boost/thread/detail/config.hpp> #include <boost/throw_exception.hpp> #include <boost/assert.hpp> #include <boost/thread/exceptions.hpp> @@ -94,7 +94,7 @@ namespace boost { namespace win32 { - + # ifdef _WIN64 typedef unsigned __int64 ulong_ptr; # else @@ -170,20 +170,20 @@ namespace boost auto_reset_event=false, manual_reset_event=true }; - + enum initial_event_state { event_initially_reset=false, event_initially_set=true }; - + inline handle create_anonymous_event(event_type type,initial_event_state state) { -#if !defined(BOOST_NO_ANSI_APIS) +#if !defined(BOOST_NO_ANSI_APIS) handle const res=win32::CreateEventA(0,type,state,0); #else handle const res=win32::CreateEventW(0,type,state,0); -#endif +#endif if(!res) { boost::throw_exception(thread_resource_error()); @@ -193,17 +193,26 @@ namespace boost inline handle create_anonymous_semaphore(long initial_count,long max_count) { -#if !defined(BOOST_NO_ANSI_APIS) +#if !defined(BOOST_NO_ANSI_APIS) handle const res=CreateSemaphoreA(0,initial_count,max_count,0); #else handle const res=CreateSemaphoreW(0,initial_count,max_count,0); -#endif +#endif if(!res) { boost::throw_exception(thread_resource_error()); } return res; } + inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count) + { +#if !defined(BOOST_NO_ANSI_APIS) + handle const res=CreateSemaphoreA(0,initial_count,max_count,0); +#else + handle const res=CreateSemaphoreW(0,initial_count,max_count,0); +#endif + return res; + } inline handle duplicate_handle(handle source) { @@ -237,7 +246,7 @@ namespace boost BOOST_VERIFY(CloseHandle(handle_to_manage)); } } - + public: explicit handle_manager(handle handle_to_manage_): handle_to_manage(handle_to_manage_) @@ -245,7 +254,7 @@ namespace boost handle_manager(): handle_to_manage(0) {} - + handle_manager& operator=(handle new_handle) { cleanup(); @@ -279,13 +288,13 @@ namespace boost { return !handle_to_manage; } - + ~handle_manager() { cleanup(); } }; - + } } } @@ -318,7 +327,7 @@ namespace boost { return _interlockedbittestandreset(x,bit)!=0; } - + } } } @@ -332,24 +341,50 @@ namespace boost { inline bool interlocked_bit_test_and_set(long* x,long bit) { +#ifndef BOOST_INTEL_CXX_VERSION __asm { mov eax,bit; mov edx,x; lock bts [edx],eax; setc al; - }; + }; +#else + bool ret; + __asm { + mov eax,bit + mov edx,x + lock bts [edx],eax + setc al + mov ret, al + }; + return ret; + +#endif } inline bool interlocked_bit_test_and_reset(long* x,long bit) { +#ifndef BOOST_INTEL_CXX_VERSION __asm { mov eax,bit; mov edx,x; lock btr [edx],eax; setc al; - }; + }; +#else + bool ret; + __asm { + mov eax,bit + mov edx,x + lock btr [edx],eax + setc al + mov ret, al + }; + return ret; + +#endif } - + } } } |