summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2014-10-19 20:22:58 (GMT)
committerTobias Markmann <tm@ayena.de>2014-10-20 13:49:33 (GMT)
commit6b22dfcf59474dd016a0355a3102a1dd3692d92c (patch)
tree2b1fd33be433a91e81fee84fdc2bf1b52575d934 /3rdParty/Boost/src/boost/thread/detail/thread.hpp
parent38b0cb785fea8eae5e48fae56440695fdfd10ee1 (diff)
downloadswift-6b22dfcf59474dd016a0355a3102a1dd3692d92c.zip
swift-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.hpp304
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