diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread/detail/thread.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/thread.hpp | 423 |
1 files changed, 272 insertions, 151 deletions
diff --git a/3rdParty/Boost/src/boost/thread/detail/thread.hpp b/3rdParty/Boost/src/boost/thread/detail/thread.hpp index 005555e..2590f45 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/thread.hpp @@ -4,7 +4,9 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-10 Anthony Williams - +// (C) Copyright 20011-12 Vicente J. Botet Escriba + +#include <boost/thread/detail/config.hpp> #include <boost/thread/exceptions.hpp> #ifndef BOOST_NO_IOSTREAM #include <ostream> @@ -13,7 +15,6 @@ #include <boost/thread/mutex.hpp> #include <boost/thread/xtime.hpp> #include <boost/thread/detail/thread_heap_alloc.hpp> -#include <boost/utility.hpp> #include <boost/assert.hpp> #include <list> #include <algorithm> @@ -22,8 +23,18 @@ #include <boost/bind.hpp> #include <stdlib.h> #include <memory> +//#include <vector> +//#include <utility> #include <boost/utility/enable_if.hpp> #include <boost/type_traits/remove_reference.hpp> +#include <boost/io/ios_state.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/type_traits/decay.hpp> +#include <boost/functional/hash.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif #include <boost/config/abi_prefix.hpp> @@ -34,6 +45,7 @@ namespace boost { + namespace detail { template<typename F> @@ -41,30 +53,33 @@ namespace boost public detail::thread_data_base { public: -#ifndef BOOST_NO_RVALUE_REFERENCES - thread_data(F&& f_): - f(static_cast<F&&>(f_)) - {} - thread_data(F& f_): - f(f_) - {} + BOOST_THREAD_NO_COPYABLE(thread_data) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + thread_data(BOOST_THREAD_RV_REF(F) f_): + f(boost::forward<F>(f_)) + {} +// This overloading must be removed if we want the packaged_task's tests to pass. +// thread_data(F& f_): +// f(f_) +// {} #else - thread_data(F f_): - f(f_) + + thread_data(BOOST_THREAD_RV_REF(F) f_): + f(f_) {} - thread_data(detail::thread_move_t<F> f_): + thread_data(F f_): f(f_) {} -#endif +#endif + //thread_data() {} + void run() { f(); } + private: F f; - - void operator=(thread_data&); - thread_data(thread_data&); }; template<typename F> @@ -73,14 +88,11 @@ namespace boost { private: F& f; - - void operator=(thread_data&); - thread_data(thread_data&); public: + BOOST_THREAD_NO_COPYABLE(thread_data) thread_data(boost::reference_wrapper<F> f_): f(f_) {} - void run() { f(); @@ -93,45 +105,48 @@ namespace boost { private: F& f; - void operator=(thread_data&); - thread_data(thread_data&); public: + BOOST_THREAD_NO_COPYABLE(thread_data) thread_data(const boost::reference_wrapper<F> f_): f(f_) {} - void run() { f(); } }; } - + class BOOST_THREAD_DECL thread { + public: + typedef thread_attributes attributes; + + BOOST_THREAD_MOVABLE_ONLY(thread) private: - thread(thread&); - thread& operator=(thread&); void release_handle(); - + detail::thread_data_ptr thread_info; void start_thread(); - + void start_thread(const attributes& attr); + explicit thread(detail::thread_data_ptr data); detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const; -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template<typename F> - static inline detail::thread_data_ptr make_thread_info(F&& f) + static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f) { - return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >(static_cast<F&&>(f))); + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<typename boost::remove_reference<F>::type> >( + boost::forward<F>(f))); } static inline detail::thread_data_ptr make_thread_info(void (*f)()) { - return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >(static_cast<void(*&&)()>(f))); + return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >( + boost::forward<void(*)()>(f))); } #else template<typename F> @@ -140,7 +155,7 @@ namespace boost return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f)); } template<typename F> - static inline detail::thread_data_ptr make_thread_info(boost::detail::thread_move_t<F> f) + static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f) { return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f)); } @@ -148,46 +163,42 @@ namespace boost #endif struct dummy; public: +#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. #if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) - thread(const volatile thread&); -#endif - thread(); - ~thread(); - -#ifndef BOOST_NO_RVALUE_REFERENCES -#ifdef BOOST_MSVC - template <class F> - explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0): - thread_info(make_thread_info(static_cast<F&&>(f))) - { - start_thread(); - } -#else - template <class F> - thread(F&& f): - thread_info(make_thread_info(static_cast<F&&>(f))) - { - start_thread(); - } + thread(const volatile thread&); #endif - - thread(thread&& other) +#endif + thread() BOOST_NOEXCEPT; + ~thread() + { + #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE + if (joinable()) { + std::terminate(); + } + #else + detach(); + #endif + } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template < + class F + > + explicit thread(BOOST_THREAD_RV_REF(F) f + , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0 + ): + thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f)))) { - thread_info.swap(other.thread_info); + start_thread(); } - - thread& operator=(thread&& other) + template < + class F + > + thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f): + thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f)))) { - thread_info=other.thread_info; - other.thread_info.reset(); - return *this; + start_thread(attrs); } - thread&& move() - { - return static_cast<thread&&>(*this); - } - #else #ifdef BOOST_NO_SFINAE template <class F> @@ -196,57 +207,73 @@ namespace boost { start_thread(); } + template <class F> + thread(attributes& attrs, F f): + thread_info(make_thread_info(f)) + { + start_thread(attrs); + } #else template <class F> - explicit thread(F f,typename disable_if<boost::is_convertible<F&,detail::thread_move_t<F> >, dummy* >::type=0): + explicit thread(F f + // todo Disable also if Or is_same<typename decay<F>::type, thread> + , typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0): thread_info(make_thread_info(f)) { start_thread(); } + template <class F> + thread(attributes& attrs, F f + , typename disable_if<boost::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0): + thread_info(make_thread_info(f)) + { + start_thread(attrs); + } #endif - template <class F> - explicit thread(detail::thread_move_t<F> f): + explicit thread(BOOST_THREAD_RV_REF(F) f + , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0 + ): thread_info(make_thread_info(f)) { start_thread(); } - thread(detail::thread_move_t<thread> x) + template <class F> + thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f): + thread_info(make_thread_info(f)) { - thread_info=x->thread_info; - x->thread_info.reset(); + start_thread(attrs); } - -#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) - thread& operator=(thread x) - { - swap(x); - return *this; - } -#else - thread& operator=(detail::thread_move_t<thread> x) +#endif + thread(BOOST_THREAD_RV_REF(thread) x) { - thread new_thread(x); - swap(new_thread); - return *this; + thread_info=BOOST_THREAD_RV(x).thread_info; + BOOST_THREAD_RV(x).thread_info.reset(); } -#endif - operator detail::thread_move_t<thread>() +#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) + thread& operator=(thread x) { - return move(); + swap(x); + return *this; } - - detail::thread_move_t<thread> move() +#endif +#endif + + thread& operator=(BOOST_THREAD_RV_REF(thread) other) BOOST_NOEXCEPT { - detail::thread_move_t<thread> x(*this); - return x; - } +#if defined BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE + if (joinable()) std::terminate(); #endif + thread_info=BOOST_THREAD_RV(other).thread_info; + BOOST_THREAD_RV(other).thread_info.reset(); + return *this; + } template <class F,class A1> - thread(F f,A1 a1): + thread(F f,A1 a1,typename disable_if<boost::is_convertible<F&,thread_attributes >, dummy* >::type=0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1))) { start_thread(); @@ -307,40 +334,102 @@ namespace boost start_thread(); } - void swap(thread& x) + void swap(thread& x) BOOST_NOEXCEPT { thread_info.swap(x.thread_info); } - class id; - id get_id() const; + class BOOST_SYMBOL_VISIBLE id; + id get_id() const BOOST_NOEXCEPT; - bool joinable() const; + bool joinable() const BOOST_NOEXCEPT; void join(); - bool timed_join(const system_time& wait_until); +#ifdef BOOST_THREAD_USES_CHRONO + template <class Rep, class Period> + bool try_join_for(const chrono::duration<Rep, Period>& rel_time) + { + return try_join_until(chrono::steady_clock::now() + rel_time); + } + template <class Clock, class Duration> + bool try_join_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_join_until(s_now + ceil<nanoseconds>(t - c_now)); + } + template <class Duration> + bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t) + { + using namespace chrono; + typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; + return try_join_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); + } +#endif +#if defined(BOOST_THREAD_PLATFORM_WIN32) + bool timed_join(const system_time& abs_time); + private: + bool do_try_join_until(uintmax_t milli); + public: +#ifdef BOOST_THREAD_USES_CHRONO + bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) + { + chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); + return do_try_join_until(rel_time.count()); + } +#endif + + +#else + bool timed_join(const system_time& abs_time) + { + struct timespec const ts=detail::get_timespec(abs_time); + return do_try_join_until(ts); + } +#ifdef BOOST_THREAD_USES_CHRONO + bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) + { + using namespace chrono; + nanoseconds d = tp.time_since_epoch(); + timespec ts; + seconds s = duration_cast<seconds>(d); + ts.tv_sec = static_cast<long>(s.count()); + ts.tv_nsec = static_cast<long>((d - s).count()); + return do_try_join_until(ts); + } +#endif + private: + bool do_try_join_until(struct timespec const &timeout); + public: + +#endif template<typename TimeDuration> inline bool timed_join(TimeDuration const& rel_time) { return timed_join(get_system_time()+rel_time); } + void detach(); - static unsigned hardware_concurrency(); + static unsigned hardware_concurrency() BOOST_NOEXCEPT; +#define BOOST_THREAD_DEFINES_THREAD_NATIVE_HANDLE typedef detail::thread_data_base::native_handle_type native_handle_type; native_handle_type native_handle(); +#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 + // Use thread::id when comparisions are needed // backwards compatibility bool operator==(const thread& other) const; bool operator!=(const thread& other) const; - - static inline void yield() +#endif + static inline void yield() BOOST_NOEXCEPT { this_thread::yield(); } - + static inline void sleep(const system_time& xt) { this_thread::sleep(xt); @@ -348,85 +437,110 @@ namespace boost // extensions void interrupt(); - bool interruption_requested() const; + bool interruption_requested() const BOOST_NOEXCEPT; }; - inline void swap(thread& lhs,thread& rhs) + inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT { return lhs.swap(rhs); } - -#ifndef BOOST_NO_RVALUE_REFERENCES - inline thread&& move(thread& t) - { - return static_cast<thread&&>(t); - } - inline thread&& move(thread&& t) + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + inline thread&& move(thread& t) BOOST_NOEXCEPT { return static_cast<thread&&>(t); } -#else - inline detail::thread_move_t<thread> move(detail::thread_move_t<thread> t) - { - return t; - } #endif + BOOST_THREAD_DCL_MOVABLE(thread) + namespace this_thread { - thread::id BOOST_THREAD_DECL get_id(); + thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT; void BOOST_THREAD_DECL interruption_point(); - bool BOOST_THREAD_DECL interruption_enabled(); - bool BOOST_THREAD_DECL interruption_requested(); + bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT; + bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT; - inline void sleep(xtime const& abs_time) + inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time) { sleep(system_time(abs_time)); } } - class thread::id + class BOOST_SYMBOL_VISIBLE thread::id { private: - detail::thread_data_ptr thread_data; - - id(detail::thread_data_ptr thread_data_): + friend inline + std::size_t + hash_value(const thread::id &v) + { +#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return hash_value(v.thread_data); +#else + return hash_value(v.thread_data.get()); +#endif + } + +#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID +#if defined(BOOST_THREAD_PLATFORM_WIN32) + typedef unsigned int data; +#else + typedef thread::native_handle_type data; +#endif +#else + typedef detail::thread_data_ptr data; +#endif + data thread_data; + + id(data thread_data_): thread_data(thread_data_) {} friend class thread; - friend id BOOST_THREAD_DECL this_thread::get_id(); + friend id BOOST_THREAD_DECL this_thread::get_id() BOOST_NOEXCEPT; public: - id(): - thread_data() + id() BOOST_NOEXCEPT: +#if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID +#if defined(BOOST_THREAD_PLATFORM_WIN32) + thread_data(0) +#else + thread_data(0) +#endif +#else + thread_data() +#endif + {} + + id(const id& other) BOOST_NOEXCEPT : + thread_data(other.thread_data) {} - - bool operator==(const id& y) const + + bool operator==(const id& y) const BOOST_NOEXCEPT { return thread_data==y.thread_data; } - - bool operator!=(const id& y) const + + bool operator!=(const id& y) const BOOST_NOEXCEPT { return thread_data!=y.thread_data; } - - bool operator<(const id& y) const + + bool operator<(const id& y) const BOOST_NOEXCEPT { return thread_data<y.thread_data; } - - bool operator>(const id& y) const + + bool operator>(const id& y) const BOOST_NOEXCEPT { return y.thread_data<thread_data; } - - bool operator<=(const id& y) const + + bool operator<=(const id& y) const BOOST_NOEXCEPT { return !(y.thread_data<thread_data); } - - bool operator>=(const id& y) const + + bool operator>=(const id& y) const BOOST_NOEXCEPT { return !(thread_data<y.thread_data); } @@ -434,12 +548,14 @@ namespace boost #ifndef BOOST_NO_IOSTREAM #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS template<class charT, class traits> - friend std::basic_ostream<charT, traits>& + friend BOOST_SYMBOL_VISIBLE + std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const id& x) { if(x.thread_data) { - return os<<x.thread_data; + io::ios_flags_saver ifs( os ); + return os<< std::hex << x.thread_data; } else { @@ -448,12 +564,14 @@ namespace boost } #else template<class charT, class traits> - std::basic_ostream<charT, traits>& + BOOST_SYMBOL_VISIBLE + std::basic_ostream<charT, traits>& print(std::basic_ostream<charT, traits>& os) const { if(thread_data) { - return os<<thread_data; + io::ios_flags_saver ifs( os ); + return os<< std::hex << thread_data; } else { @@ -467,23 +585,26 @@ namespace boost #if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template<class charT, class traits> - std::basic_ostream<charT, traits>& + BOOST_SYMBOL_VISIBLE + std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const thread::id& x) { return x.print(os); } #endif +#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 inline bool thread::operator==(const thread& other) const { return get_id()==other.get_id(); } - + inline bool thread::operator!=(const thread& other) const { return get_id()!=other.get_id(); } - +#endif + namespace detail { struct thread_exit_function_base @@ -492,26 +613,26 @@ namespace boost {} virtual void operator()()=0; }; - + template<typename F> struct thread_exit_function: thread_exit_function_base { F f; - + thread_exit_function(F f_): f(f_) {} - + void operator()() { f(); } }; - + void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*); } - + namespace this_thread { template<typename F> |