summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/thread/detail/thread.hpp')
-rw-r--r--3rdParty/Boost/src/boost/thread/detail/thread.hpp423
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>