diff options
Diffstat (limited to 'boost/thread/detail')
-rw-r--r-- | boost/thread/detail/config.hpp | 113 | ||||
-rw-r--r-- | boost/thread/detail/delete.hpp | 45 | ||||
-rw-r--r-- | boost/thread/detail/memory.hpp | 54 | ||||
-rw-r--r-- | boost/thread/detail/move.hpp | 182 | ||||
-rw-r--r-- | boost/thread/detail/platform.hpp | 4 | ||||
-rw-r--r-- | boost/thread/detail/thread.hpp | 340 | ||||
-rw-r--r-- | boost/thread/detail/thread_interruption.hpp | 23 |
7 files changed, 621 insertions, 140 deletions
diff --git a/boost/thread/detail/config.hpp b/boost/thread/detail/config.hpp index b59550669c..d9270df8af 100644 --- a/boost/thread/detail/config.hpp +++ b/boost/thread/detail/config.hpp @@ -1,5 +1,6 @@ // Copyright (C) 2001-2003 // William E. Kempf +// Copyright (C) 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) @@ -10,13 +11,117 @@ #include <boost/config.hpp> #include <boost/detail/workaround.hpp> +// This compiler doesn't support Boost.Chrono +#if defined __IBMCPP__ && (__IBMCPP__ < 1100) +#define BOOST_THREAD_DONT_USE_CHRONO +#endif + +// This compiler doesn't support Boost.Move +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) +#define BOOST_THREAD_DONT_USE_MOVE +#endif +// This compiler doesn't support Boost.Container Allocators files +#if defined __SUNPRO_CC +#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#endif + +#if defined _WIN32_WCE && _WIN32_WCE==0x501 +#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#endif + +#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID +#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID +#endif + +// Default version is 2 #if !defined BOOST_THREAD_VERSION -#define BOOST_THREAD_VERSION 1 +#define BOOST_THREAD_VERSION 2 #else -#if BOOST_THREAD_VERSION!=1 && BOOST_THREAD_VERSION!=2 -#error "BOOST_THREAD_VERSION must be 1 or 2" +#if BOOST_THREAD_VERSION!=2 && BOOST_THREAD_VERSION!=3 +#error "BOOST_THREAD_VERSION must be 2 or 3" +#endif +#endif + +// Uses Boost.System by default if not stated the opposite defining BOOST_THREAD_DONT_USE_SYSTEM +#if ! defined BOOST_THREAD_DONT_USE_SYSTEM +#define BOOST_THREAD_USES_SYSTEM +#endif + +// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO or BOOST_THREAD_DONT_USE_SYSTEM +#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_DONT_USE_SYSTEM +#define BOOST_THREAD_USES_CHRONO +#endif + +// Don't provided by default in version 1. +#if defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION explicit +#else +#define BOOST_THREAD_EXPLICIT_LOCK_CONVERSION +#endif + + +// Uses Boost.Move by default if not stated the opposite defining BOOST_THREAD_DONT_USE_MOVE +#if ! defined BOOST_THREAD_DONT_USE_MOVE +#if ! defined BOOST_THREAD_USES_MOVE +//#define BOOST_THREAD_USES_MOVE +#endif #endif + +#if BOOST_THREAD_VERSION==2 +#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY +#define BOOST_THREAD_PROMISE_LAZY +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 +#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 +#endif +#endif + +#if BOOST_THREAD_VERSION==3 +#if ! defined BOOST_THREAD_DONT_PROVIDE_ONCE_CXX11 +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE +#define BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE +#define BOOST_THREAD_PROVIDES_THREAD_MOVE_ASSIGN_CALLS_TERMINATE_IF_JOINABLE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE +#define BOOST_THREAD_PROVIDES_FUTURE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN +#endif +#if ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 +#define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 +#endif +#if ! defined BOOST_THREAD_DONT_USE_MOVE +#if ! defined BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_USES_MOVE +#endif +#endif + +#endif + +// BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN is defined if BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#if defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN +#endif + +// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52 +// BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55 +#if ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 +#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 #endif #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) @@ -26,7 +131,7 @@ # pragma warn -8066 // Unreachable code #endif -#include "platform.hpp" +#include <boost/thread/detail/platform.hpp> // provided for backwards compatibility, since this // macro was used for several releases by mistake. diff --git a/boost/thread/detail/delete.hpp b/boost/thread/detail/delete.hpp new file mode 100644 index 0000000000..9e56d4429e --- /dev/null +++ b/boost/thread/detail/delete.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 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) + +#ifndef BOOST_THREAD_DETAIL_DELETE_HPP +#define BOOST_THREAD_DETAIL_DELETE_HPP + +#include <boost/config.hpp> + +/** + * BOOST_THREAD_DELETE_COPY_CTOR deletes the copy constructor when the compiler supports it or + * makes it private. + * + * BOOST_THREAD_DELETE_COPY_ASSIGN deletes the copy assignment when the compiler supports it or + * makes it private. + */ +#ifndef BOOST_NO_DELETED_FUNCTIONS +#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \ + CLASS(CLASS const&) = delete; \ + +#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \ + CLASS& operator=(CLASS const&) = delete; + +#else // BOOST_NO_DELETED_FUNCTIONS +#define BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \ + private: \ + CLASS(CLASS&); \ + public: + +#define BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) \ + private: \ + CLASS& operator=(CLASS&); \ + public: +#endif // BOOST_NO_DELETED_FUNCTIONS + +/** + * BOOST_THREAD_NO_COPYABLE deletes the copy constructor and assignment when the compiler supports it or + * makes them private. + */ +#define BOOST_THREAD_NO_COPYABLE(CLASS) \ + BOOST_THREAD_DELETE_COPY_CTOR(CLASS) \ + BOOST_THREAD_DELETE_COPY_ASSIGN(CLASS) + +#endif // BOOST_THREAD_DETAIL_DELETE_HPP diff --git a/boost/thread/detail/memory.hpp b/boost/thread/detail/memory.hpp new file mode 100644 index 0000000000..7d47efc781 --- /dev/null +++ b/boost/thread/detail/memory.hpp @@ -0,0 +1,54 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright 2011-2012 Vicente J. Botet Escriba +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/thread for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_THREAD_DETAIL_MEMORY_HPP +#define BOOST_THREAD_DETAIL_MEMORY_HPP + +#include <boost/container/allocator_traits.hpp> +#include <boost/container/scoped_allocator.hpp> +#include <boost/config.hpp> + +namespace boost +{ + namespace thread_detail + { + template <class _Alloc> + class allocator_destructor + { + typedef container::allocator_traits<_Alloc> alloc_traits; + public: + typedef typename alloc_traits::pointer pointer; + typedef typename alloc_traits::size_type size_type; + private: + _Alloc& alloc_; + size_type s_; + public: + allocator_destructor(_Alloc& a, size_type s)BOOST_NOEXCEPT + : alloc_(a), s_(s) + {} + void operator()(pointer p)BOOST_NOEXCEPT + { + alloc_traits::deallocate(alloc_, p, s_); + } + }; + } //namespace thread_detail + + typedef container::allocator_arg_t allocator_arg_t; + BOOST_CONSTEXPR_OR_CONST allocator_arg_t allocator_arg = {}; + + template <class T, class Alloc> + struct uses_allocator: public container::uses_allocator<T, Alloc> + { + }; + +} // namespace boost + + +#endif // BOOST_THREAD_DETAIL_MEMORY_HPP diff --git a/boost/thread/detail/move.hpp b/boost/thread/detail/move.hpp index 665a0b5978..748b8dc241 100644 --- a/boost/thread/detail/move.hpp +++ b/boost/thread/detail/move.hpp @@ -2,6 +2,7 @@ // 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 #ifndef BOOST_THREAD_MOVE_HPP #define BOOST_THREAD_MOVE_HPP @@ -11,10 +12,12 @@ #include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/decay.hpp> #endif +#include <boost/thread/detail/delete.hpp> #include <boost/move/move.hpp> - #include <boost/config/abi_prefix.hpp> namespace boost @@ -22,6 +25,8 @@ namespace boost namespace detail { + template <typename T> + struct has_move_emulation_enabled_aux_dummy_specialization; template<typename T> struct thread_move_t { @@ -44,6 +49,7 @@ namespace boost }; } + #ifndef BOOST_NO_SFINAE template<typename T> typename enable_if<boost::is_convertible<T&,boost::detail::thread_move_t<T> >, boost::detail::thread_move_t<T> >::type move(T& t) @@ -57,9 +63,183 @@ namespace boost { return t; } +} + +#if ! defined BOOST_NO_RVALUE_REFERENCES + +#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) +#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG +#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END +#define BOOST_THREAD_RV(V) V +#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE +#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) +#define BOOST_THREAD_DCL_MOVABLE(TYPE) +#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ + namespace detail { \ + template <typename T> \ + struct has_move_emulation_enabled_aux_dummy_specialization< + +#define BOOST_THREAD_DCL_MOVABLE_END > \ + : integral_constant<bool, true> \ + {}; \ + } + +#elif ! defined BOOST_NO_RVALUE_REFERENCES && defined BOOST_MSVC + +#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) +#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG +#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END +#define BOOST_THREAD_RV(V) V +#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE +#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) +#define BOOST_THREAD_DCL_MOVABLE(TYPE) +#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ + namespace detail { \ + template <typename T> \ + struct has_move_emulation_enabled_aux_dummy_specialization< + +#define BOOST_THREAD_DCL_MOVABLE_END > \ + : integral_constant<bool, true> \ + {}; \ + } + +#else + +#if defined BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_RV_REF(TYPE) BOOST_RV_REF(TYPE) +#define BOOST_THREAD_RV_REF_BEG BOOST_RV_REF_BEG +#define BOOST_THREAD_RV_REF_END BOOST_RV_REF_END +#define BOOST_THREAD_RV(V) V +#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) +#define BOOST_THREAD_DCL_MOVABLE(TYPE) +#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ + namespace detail { \ + template <typename T> \ + struct has_move_emulation_enabled_aux_dummy_specialization< + +#define BOOST_THREAD_DCL_MOVABLE_END > \ + : integral_constant<bool, true> \ + {}; \ + } + +#else + +#define BOOST_THREAD_RV_REF(TYPE) boost::detail::thread_move_t< TYPE > +#define BOOST_THREAD_RV_REF_BEG boost::detail::thread_move_t< +#define BOOST_THREAD_RV_REF_END > +#define BOOST_THREAD_RV(V) (*V) +#define BOOST_THREAD_FWD_REF(TYPE) BOOST_FWD_REF(TYPE) + +#define BOOST_THREAD_DCL_MOVABLE(TYPE) \ +template <> \ +struct has_move_emulation_enabled_aux< TYPE > \ + : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \ +{}; + +#define BOOST_THREAD_DCL_MOVABLE_BEG(T) \ +template <typename T> \ +struct has_move_emulation_enabled_aux< + +#define BOOST_THREAD_DCL_MOVABLE_END > \ + : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> \ +{}; + +#endif + +namespace boost +{ +namespace detail +{ + template <typename T> + BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) + make_rv_ref(T v) BOOST_NOEXCEPT + { + return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); + } +// template <typename T> +// BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) +// make_rv_ref(T &v) BOOST_NOEXCEPT +// { +// return (BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); +// } +// template <typename T> +// const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type) +// make_rv_ref(T const&v) BOOST_NOEXCEPT +// { +// return (const BOOST_THREAD_RV_REF(typename ::boost::remove_cv<typename ::boost::remove_reference<T>::type>::type))(v); +// } +} +} + +#define BOOST_THREAD_MAKE_RV_REF(RVALUE) RVALUE.move() +//#define BOOST_THREAD_MAKE_RV_REF(RVALUE) boost::detail::make_rv_ref(RVALUE) +#endif + + +#if ! defined BOOST_NO_RVALUE_REFERENCES + +#define BOOST_THREAD_MOVABLE(TYPE) + +#else + +#if defined BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_MOVABLE(TYPE) \ + ::boost::rv<TYPE>& move() BOOST_NOEXCEPT \ + { \ + return *static_cast< ::boost::rv<TYPE>* >(this); \ + } \ + const ::boost::rv<TYPE>& move() const BOOST_NOEXCEPT \ + { \ + return *static_cast<const ::boost::rv<TYPE>* >(this); \ + } \ + operator ::boost::rv<TYPE>&() \ + { \ + return *static_cast< ::boost::rv<TYPE>* >(this); \ + } \ + operator const ::boost::rv<TYPE>&() const \ + { \ + return *static_cast<const ::boost::rv<TYPE>* >(this); \ + }\ +#else + +#define BOOST_THREAD_MOVABLE(TYPE) \ + operator ::boost::detail::thread_move_t<TYPE>() BOOST_NOEXCEPT \ + { \ + return move(); \ + } \ + ::boost::detail::thread_move_t<TYPE> move() BOOST_NOEXCEPT \ + { \ + ::boost::detail::thread_move_t<TYPE> x(*this); \ + return x; \ + } \ + +#endif +#endif + +#define BOOST_THREAD_MOVABLE_ONLY(TYPE) \ + BOOST_THREAD_NO_COPYABLE(TYPE) \ + BOOST_THREAD_MOVABLE(TYPE) \ + +#define BOOST_THREAD_COPYABLE_AND_MOVABLE(TYPE) \ + BOOST_THREAD_MOVABLE(TYPE) \ + + + +#ifndef BOOST_NO_RVALUE_REFERENCES +namespace boost +{ namespace thread_detail + { + template <class T> + typename decay<T>::type + decay_copy(T&& t) + { + return boost::forward<T>(t); + } + } } +#endif #include <boost/config/abi_suffix.hpp> diff --git a/boost/thread/detail/platform.hpp b/boost/thread/detail/platform.hpp index 58601b04b2..1f33b1a67a 100644 --- a/boost/thread/detail/platform.hpp +++ b/boost/thread/detail/platform.hpp @@ -19,6 +19,7 @@ // choose platform #if defined(linux) || defined(__linux) || defined(__linux__) # define BOOST_THREAD_LINUX +//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(100000) #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) # define BOOST_THREAD_BSD #elif defined(sun) || defined(__sun) @@ -35,6 +36,7 @@ # define BOOST_THREAD_BEOS #elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) # define BOOST_THREAD_MACOS +//# define BOOST_THREAD_WAIT_BUG boost::posix_time::microseconds(1000) #elif defined(__IBMCPP__) || defined(_AIX) # define BOOST_THREAD_AIX #elif defined(__amigaos__) @@ -55,7 +57,7 @@ // dispatcher table. If there is no entry for a platform but pthreads is // available on the platform, pthread is choosen as default. If nothing is // available the preprocessor will fail with a diagnostic message. - + #if defined(BOOST_THREAD_POSIX) # define BOOST_THREAD_PLATFORM_PTHREAD #else diff --git a/boost/thread/detail/thread.hpp b/boost/thread/detail/thread.hpp index 7ac342bfc6..3c71b53cf7 100644 --- a/boost/thread/detail/thread.hpp +++ b/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> @@ -25,6 +26,13 @@ #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> @@ -35,6 +43,7 @@ namespace boost { + namespace detail { template<typename F> @@ -42,18 +51,21 @@ namespace boost public detail::thread_data_base { public: + BOOST_THREAD_NO_COPYABLE(thread_data) #ifndef BOOST_NO_RVALUE_REFERENCES - thread_data(F&& f_): - f(static_cast<F&&>(f_)) - {} - thread_data(F& f_): - f(f_) - {} + 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 @@ -63,9 +75,6 @@ namespace boost } private: F f; - - void operator=(thread_data&); - thread_data(thread_data&); }; template<typename F> @@ -74,14 +83,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(); @@ -94,13 +100,11 @@ 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(); @@ -110,15 +114,18 @@ namespace boost 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); @@ -126,13 +133,15 @@ namespace boost #ifndef BOOST_NO_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> @@ -141,7 +150,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)); } @@ -149,44 +158,40 @@ 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(); - } #endif - - thread(thread&& other) + thread() BOOST_NOEXCEPT; + ~thread() { - thread_info.swap(other.thread_info); + #if defined BOOST_THREAD_PROVIDES_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE + if (joinable()) { + std::terminate(); + } + #else + detach(); + #endif } - - thread& operator=(thread&& other) +#ifndef BOOST_NO_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=other.thread_info; - other.thread_info.reset(); - return *this; + start_thread(); } - - thread&& move() + 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)))) { - return static_cast<thread&&>(*this); + start_thread(attrs); } #else @@ -197,57 +202,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); } - +#endif + thread(BOOST_THREAD_RV_REF(thread) x) + { + thread_info=BOOST_THREAD_RV(x).thread_info; + BOOST_THREAD_RV(x).thread_info.reset(); + } +#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) { swap(x); return *this; } -#else - thread& operator=(detail::thread_move_t<thread> x) - { - thread new_thread(x); - swap(new_thread); - return *this; - } #endif - operator detail::thread_move_t<thread>() - { - return move(); - } +#endif - detail::thread_move_t<thread> move() + 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(); @@ -308,36 +329,92 @@ namespace boost start_thread(); } - void swap(thread& x) + void swap(thread& x) BOOST_NOEXCEPT { thread_info.swap(x.thread_info); } class BOOST_SYMBOL_VISIBLE id; - id get_id() const; + 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); + +#ifdef BOOST_THREAD_USES_CHRONO + bool try_join_until(const chrono::time_point<chrono::system_clock, chrono::nanoseconds>& tp); +#endif + public: + +#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(); + void detach() BOOST_NOEXCEPT; + + 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(); } @@ -349,37 +426,30 @@ 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) + inline thread&& move(thread& t) BOOST_NOEXCEPT { return static_cast<thread&&>(t); } - inline thread&& move(thread&& t) - { - 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 BOOST_SYMBOL_VISIBLE void sleep(xtime const& abs_time) { @@ -390,48 +460,76 @@ namespace boost class BOOST_SYMBOL_VISIBLE thread::id { private: - 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 + } - id(detail::thread_data_ptr thread_data_): +#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): + 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); } @@ -440,7 +538,7 @@ namespace boost #ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS template<class charT, class traits> friend BOOST_SYMBOL_VISIBLE - std::basic_ostream<charT, traits>& + std::basic_ostream<charT, traits>& operator<<(std::basic_ostream<charT, traits>& os, const id& x) { if(x.thread_data) @@ -456,12 +554,13 @@ namespace boost #else template<class charT, class traits> BOOST_SYMBOL_VISIBLE - std::basic_ostream<charT, traits>& + 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 { @@ -483,6 +582,7 @@ namespace boost } #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(); @@ -492,6 +592,7 @@ namespace boost { return get_id()!=other.get_id(); } +#endif namespace detail { @@ -521,13 +622,6 @@ namespace boost void BOOST_THREAD_DECL add_thread_exit_function(thread_exit_function_base*); } -#ifdef BOOST_NO_RVALUE_REFERENCES - template <> - struct has_move_emulation_enabled_aux<thread> - : BOOST_MOVE_BOOST_NS::integral_constant<bool, true> - {}; -#endif - namespace this_thread { template<typename F> diff --git a/boost/thread/detail/thread_interruption.hpp b/boost/thread/detail/thread_interruption.hpp index 60c0e65b8c..f1a165c33e 100644 --- a/boost/thread/detail/thread_interruption.hpp +++ b/boost/thread/detail/thread_interruption.hpp @@ -4,6 +4,10 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007-9 Anthony Williams +// (C) Copyright 2012 Vicente J. Botet Escriba + +#include <boost/thread/detail/config.hpp> +#include <boost/thread/detail/delete.hpp> namespace boost { @@ -11,23 +15,20 @@ namespace boost { class BOOST_THREAD_DECL disable_interruption { - disable_interruption(const disable_interruption&); - disable_interruption& operator=(const disable_interruption&); - - bool interruption_was_enabled; - friend class restore_interruption; + bool interruption_was_enabled; + friend class restore_interruption; public: - disable_interruption(); - ~disable_interruption(); + BOOST_THREAD_NO_COPYABLE(disable_interruption) + disable_interruption() BOOST_NOEXCEPT; + ~disable_interruption() BOOST_NOEXCEPT; }; class BOOST_THREAD_DECL restore_interruption { - restore_interruption(const restore_interruption&); - restore_interruption& operator=(const restore_interruption&); public: - explicit restore_interruption(disable_interruption& d); - ~restore_interruption(); + BOOST_THREAD_NO_COPYABLE(restore_interruption) + explicit restore_interruption(disable_interruption& d) BOOST_NOEXCEPT; + ~restore_interruption() BOOST_NOEXCEPT; }; } } |