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/detail/thread.hpp | |
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/detail/thread.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/detail/thread.hpp | 304 |
1 files changed, 260 insertions, 44 deletions
diff --git a/3rdParty/Boost/src/boost/thread/detail/thread.hpp b/3rdParty/Boost/src/boost/thread/detail/thread.hpp index 2590f45..520ca26 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/thread.hpp @@ -3,29 +3,33 @@ // 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) -// (C) Copyright 2007-10 Anthony Williams -// (C) Copyright 20011-12 Vicente J. Botet Escriba +// (C) Copyright 2007-2010 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba #include <boost/thread/detail/config.hpp> + #include <boost/thread/exceptions.hpp> #ifndef BOOST_NO_IOSTREAM #include <ostream> #endif #include <boost/thread/detail/move.hpp> #include <boost/thread/mutex.hpp> +#if defined BOOST_THREAD_USES_DATETIME #include <boost/thread/xtime.hpp> +#endif #include <boost/thread/detail/thread_heap_alloc.hpp> +#include <boost/thread/detail/make_tuple_indices.hpp> +#include <boost/thread/detail/invoke.hpp> +#include <boost/thread/detail/is_convertible.hpp> #include <boost/assert.hpp> #include <list> #include <algorithm> -#include <boost/ref.hpp> +#include <boost/core/ref.hpp> #include <boost/cstdint.hpp> #include <boost/bind.hpp> #include <stdlib.h> #include <memory> -//#include <vector> -//#include <utility> -#include <boost/utility/enable_if.hpp> +#include <boost/core/enable_if.hpp> #include <boost/type_traits/remove_reference.hpp> #include <boost/io/ios_state.hpp> #include <boost/type_traits/is_same.hpp> @@ -36,6 +40,9 @@ #include <boost/chrono/ceil.hpp> #endif +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) +#include <tuple> +#endif #include <boost/config/abi_prefix.hpp> #ifdef BOOST_MSVC @@ -48,6 +55,36 @@ namespace boost namespace detail { + +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + + template<typename F, class ...ArgTypes> + class thread_data: + public detail::thread_data_base + { + public: + BOOST_THREAD_NO_COPYABLE(thread_data) + thread_data(BOOST_THREAD_RV_REF(F) f_, BOOST_THREAD_RV_REF(ArgTypes)... args_): + fp(boost::forward<F>(f_), boost::forward<ArgTypes>(args_)...) + {} + template <std::size_t ...Indices> + void run2(tuple_indices<Indices...>) + { + + invoke(std::move(std::get<0>(fp)), std::move(std::get<Indices>(fp))...); + } + void run() + { + typedef typename make_tuple_indices<std::tuple_size<std::tuple<F, ArgTypes...> >::value, 1>::type index_type; + + run2(index_type()); + } + + private: + std::tuple<typename decay<F>::type, typename decay<ArgTypes>::type...> fp; + }; +#else // defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + template<typename F> class thread_data: public detail::thread_data_base @@ -115,6 +152,7 @@ namespace boost f(); } }; +#endif } class BOOST_THREAD_DECL thread @@ -125,24 +163,55 @@ namespace boost BOOST_THREAD_MOVABLE_ONLY(thread) private: + struct dummy; + void release_handle(); detail::thread_data_ptr thread_info; - void start_thread(); - void start_thread(const attributes& attr); + private: + bool start_thread_noexcept(); + bool start_thread_noexcept(const attributes& attr); + //public: + void start_thread() + { + if (!start_thread_noexcept()) + { + boost::throw_exception(thread_resource_error()); + } + } + void start_thread(const attributes& attr) + { + if (!start_thread_noexcept(attr)) + { + boost::throw_exception(thread_resource_error()); + } + } explicit thread(detail::thread_data_ptr data); detail::thread_data_ptr get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const; #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + template<typename F, class ...ArgTypes> + static inline detail::thread_data_ptr make_thread_info(BOOST_THREAD_RV_REF(F) f, BOOST_THREAD_RV_REF(ArgTypes)... args) + { + return detail::thread_data_ptr(detail::heap_new< + detail::thread_data<typename boost::remove_reference<F>::type, ArgTypes...> + >( + boost::forward<F>(f), boost::forward<ArgTypes>(args)... + ) + ); + } +#else template<typename 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> >( boost::forward<F>(f))); } +#endif static inline detail::thread_data_ptr make_thread_info(void (*f)()) { return detail::thread_data_ptr(detail::heap_new<detail::thread_data<void(*)()> >( @@ -150,7 +219,12 @@ namespace boost } #else template<typename F> - static inline detail::thread_data_ptr make_thread_info(F f) + static inline detail::thread_data_ptr make_thread_info(F f + , typename disable_if_c< + //boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value || + is_same<typename decay<F>::type, thread>::value, + dummy* >::type=0 + ) { return detail::thread_data_ptr(detail::heap_new<detail::thread_data<F> >(f)); } @@ -161,7 +235,6 @@ 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) @@ -171,6 +244,7 @@ namespace boost thread() BOOST_NOEXCEPT; ~thread() { + #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE if (joinable()) { std::terminate(); @@ -184,7 +258,7 @@ namespace boost class F > explicit thread(BOOST_THREAD_RV_REF(F) f - , typename disable_if<is_same<typename decay<F>::type, thread>, dummy* >::type=0 + //, 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)))) { @@ -193,7 +267,7 @@ namespace boost template < class F > - thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f): + thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f): thread_info(make_thread_info(thread_detail::decay_copy(boost::forward<F>(f)))) { start_thread(attrs); @@ -208,7 +282,7 @@ namespace boost start_thread(); } template <class F> - thread(attributes& attrs, F f): + thread(attributes const& attrs, F f): thread_info(make_thread_info(f)) { start_thread(attrs); @@ -216,15 +290,19 @@ namespace boost #else template <class F> 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): + , typename disable_if_c< + boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F)>::value + //|| is_same<typename decay<F>::type, thread>::value + , 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(attributes const& attrs, F f + , typename disable_if<boost::thread_detail::is_convertible<F&,BOOST_THREAD_RV_REF(F) >, dummy* >::type=0 + ): thread_info(make_thread_info(f)) { start_thread(attrs); @@ -234,19 +312,27 @@ namespace boost 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)) +#ifdef BOOST_THREAD_USES_MOVE + thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward +#else + thread_info(make_thread_info(f)) // todo : Add forward +#endif { start_thread(); } template <class F> - thread(attributes& attrs, BOOST_THREAD_RV_REF(F) f): - thread_info(make_thread_info(f)) + thread(attributes const& attrs, BOOST_THREAD_RV_REF(F) f): +#ifdef BOOST_THREAD_USES_MOVE + thread_info(make_thread_info(boost::move<F>(f))) // todo : Add forward +#else + thread_info(make_thread_info(f)) // todo : Add forward +#endif { start_thread(attrs); } #endif - thread(BOOST_THREAD_RV_REF(thread) x) + thread(BOOST_THREAD_RV_REF(thread) x) BOOST_NOEXCEPT { thread_info=BOOST_THREAD_RV(x).thread_info; BOOST_THREAD_RV(x).thread_info.reset(); @@ -272,8 +358,32 @@ namespace boost return *this; } +#if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD) + template <class F, class Arg, class ...Args> + thread(F&& f, Arg&& arg, Args&&... args) : + thread_info(make_thread_info( + thread_detail::decay_copy(boost::forward<F>(f)), + thread_detail::decay_copy(boost::forward<Arg>(arg)), + thread_detail::decay_copy(boost::forward<Args>(args))...) + ) + + { + start_thread(); + } + template <class F, class Arg, class ...Args> + thread(attributes const& attrs, F&& f, Arg&& arg, Args&&... args) : + thread_info(make_thread_info( + thread_detail::decay_copy(boost::forward<F>(f)), + thread_detail::decay_copy(boost::forward<Arg>(arg)), + thread_detail::decay_copy(boost::forward<Args>(args))...) + ) + + { + start_thread(attrs); + } +#else template <class F,class A1> - thread(F f,A1 a1,typename disable_if<boost::is_convertible<F&,thread_attributes >, dummy* >::type=0): + thread(F f,A1 a1,typename disable_if<boost::thread_detail::is_convertible<F&,thread_attributes >, dummy* >::type=0): thread_info(make_thread_info(boost::bind(boost::type<void>(),f,a1))) { start_thread(); @@ -333,31 +443,53 @@ namespace boost { start_thread(); } - +#endif void swap(thread& x) BOOST_NOEXCEPT { thread_info.swap(x.thread_info); } - class BOOST_SYMBOL_VISIBLE id; + class id; +#ifdef BOOST_THREAD_PLATFORM_PTHREAD + inline id get_id() const BOOST_NOEXCEPT; +#else id get_id() const BOOST_NOEXCEPT; +#endif bool joinable() const BOOST_NOEXCEPT; - void join(); + private: + bool join_noexcept(); + public: + inline void join(); + #ifdef BOOST_THREAD_USES_CHRONO +#if defined(BOOST_THREAD_PLATFORM_WIN32) + template <class Rep, class Period> + bool try_join_for(const chrono::duration<Rep, Period>& rel_time) + { + chrono::milliseconds rel_time2= chrono::ceil<chrono::milliseconds>(rel_time); + return do_try_join_until(rel_time2.count()); + } +#else 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); } +#endif 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)); + bool joined= false; + do { + typename Clock::duration d = ceil<nanoseconds>(t-Clock::now()); + if (d <= Clock::duration::zero()) return false; // in case the Clock::time_point t is already reached + joined = try_join_until(s_now + d); + } while (! joined); + return true; } template <class Duration> bool try_join_until(const chrono::time_point<chrono::system_clock, Duration>& t) @@ -368,10 +500,15 @@ namespace boost } #endif #if defined(BOOST_THREAD_PLATFORM_WIN32) - bool timed_join(const system_time& abs_time); private: - bool do_try_join_until(uintmax_t milli); + bool do_try_join_until_noexcept(uintmax_t milli, bool& res); + inline bool do_try_join_until(uintmax_t milli); public: + bool timed_join(const system_time& abs_time); + //{ + // return do_try_join_until(get_milliseconds_until(wait_until)); + //} + #ifdef BOOST_THREAD_USES_CHRONO bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp) { @@ -382,49 +519,53 @@ namespace boost #else + private: + bool do_try_join_until_noexcept(struct timespec const &timeout, bool& res); + inline bool do_try_join_until(struct timespec const &timeout); + public: +#if defined BOOST_THREAD_USES_DATETIME bool timed_join(const system_time& abs_time) { - struct timespec const ts=detail::get_timespec(abs_time); + struct timespec const ts=detail::to_timespec(abs_time); return do_try_join_until(ts); } +#endif #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()); + timespec ts = boost::detail::to_timespec(d); return do_try_join_until(ts); } #endif - private: - bool do_try_join_until(struct timespec const &timeout); - public: #endif + public: +#if defined BOOST_THREAD_USES_DATETIME template<typename TimeDuration> inline bool timed_join(TimeDuration const& rel_time) { return timed_join(get_system_time()+rel_time); } - +#endif void detach(); static unsigned hardware_concurrency() BOOST_NOEXCEPT; + static unsigned physical_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 +#if defined BOOST_THREAD_PROVIDES_THREAD_EQ // Use thread::id when comparisions are needed // backwards compatibility bool operator==(const thread& other) const; bool operator!=(const thread& other) const; #endif +#if defined BOOST_THREAD_USES_DATETIME static inline void yield() BOOST_NOEXCEPT { this_thread::yield(); @@ -434,10 +575,13 @@ namespace boost { this_thread::sleep(xt); } +#endif +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS // extensions void interrupt(); bool interruption_requested() const BOOST_NOEXCEPT; +#endif }; inline void swap(thread& lhs,thread& rhs) BOOST_NOEXCEPT @@ -456,16 +600,24 @@ namespace boost namespace this_thread { +#ifdef BOOST_THREAD_PLATFORM_PTHREAD + inline thread::id get_id() BOOST_NOEXCEPT; +#else thread::id BOOST_THREAD_DECL get_id() BOOST_NOEXCEPT; +#endif +#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS void BOOST_THREAD_DECL interruption_point(); bool BOOST_THREAD_DECL interruption_enabled() BOOST_NOEXCEPT; bool BOOST_THREAD_DECL interruption_requested() BOOST_NOEXCEPT; +#endif +#if defined BOOST_THREAD_USES_DATETIME inline BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time) { sleep(system_time(abs_time)); } +#endif } class BOOST_SYMBOL_VISIBLE thread::id @@ -501,11 +653,7 @@ namespace boost public: 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 @@ -583,6 +731,61 @@ namespace boost #endif }; +#ifdef BOOST_THREAD_PLATFORM_PTHREAD + thread::id thread::get_id() const BOOST_NOEXCEPT + { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return const_cast<thread*>(this)->native_handle(); + #else + detail::thread_data_ptr const local_thread_info=(get_thread_info)(); + return (local_thread_info? id(local_thread_info) : id()); + #endif + } + + namespace this_thread + { + inline thread::id get_id() BOOST_NOEXCEPT + { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return pthread_self(); + #else + boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); + return (thread_info?thread::id(thread_info->shared_from_this()):thread::id()); + #endif + } + } +#endif + void thread::join() { + if (this_thread::get_id() == get_id()) + boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself")); + + BOOST_THREAD_VERIFY_PRECONDITION( join_noexcept(), + thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable") + ); + } + +#ifdef BOOST_THREAD_PLATFORM_PTHREAD + bool thread::do_try_join_until(struct timespec const &timeout) +#else + bool thread::do_try_join_until(uintmax_t timeout) +#endif + { + if (this_thread::get_id() == get_id()) + boost::throw_exception(thread_resource_error(static_cast<int>(system::errc::resource_deadlock_would_occur), "boost thread: trying joining itself")); + bool res; + if (do_try_join_until_noexcept(timeout, res)) + { + return res; + } + else + { + BOOST_THREAD_THROW_ELSE_RETURN( + (thread_resource_error(static_cast<int>(system::errc::invalid_argument), "boost thread: thread not joinable")), + false + ); + } + } + #if !defined(BOOST_NO_IOSTREAM) && defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) template<class charT, class traits> BOOST_SYMBOL_VISIBLE @@ -593,7 +796,7 @@ namespace boost } #endif -#if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 +#if defined BOOST_THREAD_PROVIDES_THREAD_EQ inline bool thread::operator==(const thread& other) const { return get_id()==other.get_id(); @@ -631,6 +834,19 @@ namespace boost }; void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*); + struct shared_state_base; +#if defined(BOOST_THREAD_PLATFORM_WIN32) + inline void make_ready_at_thread_exit(shared_ptr<shared_state_base> as) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->make_ready_at_thread_exit(as); + } + } +#else + void BOOST_THREAD_DECL make_ready_at_thread_exit(shared_ptr<shared_state_base> as); +#endif } namespace this_thread |