diff options
Diffstat (limited to '3rdParty/Boost/src/boost/thread')
37 files changed, 4357 insertions, 1478 deletions
| diff --git a/3rdParty/Boost/src/boost/thread/barrier.hpp b/3rdParty/Boost/src/boost/thread/barrier.hpp index 4ca30cb..4fd8988 100644 --- a/3rdParty/Boost/src/boost/thread/barrier.hpp +++ b/3rdParty/Boost/src/boost/thread/barrier.hpp @@ -2,7 +2,7 @@  // David Moore, William E. Kempf  // Copyright (C) 2007-8 Anthony Williams  // -//  Distributed under the Boost Software License, Version 1.0. (See accompanying  +//  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_BARRIER_JDM030602_HPP @@ -28,14 +28,14 @@ namespace boost              : m_threshold(count), m_count(count), m_generation(0)          {              if (count == 0) -                boost::throw_exception(std::invalid_argument("count cannot be zero.")); +                boost::throw_exception(thread_exception(system::errc::invalid_argument, "barrier constructor: count cannot be zero."));          } -     +          bool wait()          {              boost::mutex::scoped_lock lock(m_mutex);              unsigned int gen = m_generation; -         +              if (--m_count == 0)              {                  m_generation++; diff --git a/3rdParty/Boost/src/boost/thread/condition.hpp b/3rdParty/Boost/src/boost/thread/condition.hpp deleted file mode 100644 index 35b879f..0000000 --- a/3rdParty/Boost/src/boost/thread/condition.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef BOOST_THREAD_CONDITION_HPP -#define BOOST_THREAD_CONDITION_HPP -//  (C) Copyright 2007 Anthony Williams  -// -//  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) - -#include <boost/thread/condition_variable.hpp> - -namespace boost -{ -    typedef condition_variable_any condition; -} - -#endif diff --git a/3rdParty/Boost/src/boost/thread/cv_status.hpp b/3rdParty/Boost/src/boost/thread/cv_status.hpp new file mode 100644 index 0000000..99b3c0c --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/cv_status.hpp @@ -0,0 +1,26 @@ +//  cv_status.hpp +// +// Copyright (C) 2011 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_CV_STATUS_HPP +#define BOOST_THREAD_CV_STATUS_HPP + +#include <boost/detail/scoped_enum_emulation.hpp> + +namespace boost +{ + +  // enum class cv_status; +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(cv_status) +  { +    no_timeout, +    timeout +  } +  BOOST_SCOPED_ENUM_DECLARE_END(cv_status) +} + +#endif // header diff --git a/3rdParty/Boost/src/boost/thread/detail/config.hpp b/3rdParty/Boost/src/boost/thread/detail/config.hpp index 4015a6c..87bad34 100644 --- a/3rdParty/Boost/src/boost/thread/detail/config.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/config.hpp @@ -1,15 +1,138 @@  // 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  +//  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_CONFIG_WEK01032003_HPP  #define BOOST_THREAD_CONFIG_WEK01032003_HPP +// Force SIG_ATOMIC_MAX to be defined +//#ifndef __STDC_LIMIT_MACROS +//#define __STDC_LIMIT_MACROS +//#endif +  #include <boost/config.hpp>  #include <boost/detail/workaround.hpp> +#ifdef BOOST_NO_NOEXCEPT +#  define BOOST_THREAD_NOEXCEPT_OR_THROW throw() +#else +#  define BOOST_THREAD_NOEXCEPT_OR_THROW noexcept +#endif + +// This compiler doesn't support Boost.Chrono +#if defined __IBMCPP__ && (__IBMCPP__ < 1100) && ! defined BOOST_THREAD_DONT_USE_CHRONO +#define BOOST_THREAD_DONT_USE_CHRONO +#endif + +// This compiler doesn't support Boost.Move +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) && ! defined BOOST_THREAD_DONT_USE_MOVE +#define BOOST_THREAD_DONT_USE_MOVE +#endif + +// This compiler doesn't support Boost.Container Allocators files +#if defined __SUNPRO_CC && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#endif + +#if defined _WIN32_WCE && _WIN32_WCE==0x501 && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#define BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS +#endif + +#if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID +#define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID +#endif + +// Default version is 2 +#if !defined BOOST_THREAD_VERSION +#define BOOST_THREAD_VERSION 2 +#else +#if BOOST_THREAD_VERSION!=2  && BOOST_THREAD_VERSION!=3 +#error "BOOST_THREAD_VERSION must be 2 or 3" +#endif +#endif + +// Uses Boost.Chrono by default if not stated the opposite defining BOOST_THREAD_DONT_USE_CHRONO +#if ! defined BOOST_THREAD_DONT_USE_CHRONO && ! defined BOOST_THREAD_USES_CHRONO +#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 + + +#if BOOST_THREAD_VERSION==2 +#if ! defined BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY && ! defined BOOST_THREAD_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 \ + && ! defined BOOST_THREAD_PROVIDES_ONCE_CXX11 +#define BOOST_THREAD_PROVIDES_ONCE_CXX11 +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_THREAD_DESTRUCTOR_CALLS_TERMINATE_IF_JOINABLE \ + && ! defined BOOST_THREAD_PROVIDES_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 \ + && ! defined BOOST_THREAD_PROVIDES_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 \ + && ! defined BOOST_THREAD_PROVIDES_FUTURE +#define BOOST_THREAD_PROVIDES_FUTURE +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CTOR_ALLOCATORS \ + && ! defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#define BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_SHARED_MUTEX_UPWARDS_CONVERSIONS \ + && ! defined BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#define BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_EXPLICIT_LOCK_CONVERSION \ + && ! defined BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#define BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +#endif +#if ! defined BOOST_THREAD_DONT_PROVIDE_GENERIC_SHARED_MUTEX_ON_WIN \ + && ! defined BOOST_THREAD_PROVIDES_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 \ + && ! defined BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_ +#define BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 +#endif +#if ! defined BOOST_THREAD_DONT_USE_MOVE \ + && ! defined BOOST_THREAD_USES_MOVE +#define BOOST_THREAD_USES_MOVE +#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 \ +&& ! defined BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN +#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 \ +&& ! defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 +#define BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 +#endif +  #if BOOST_WORKAROUND(__BORLANDC__, < 0x600)  #  pragma warn -8008 // Condition always true/false  #  pragma warn -8080 // Identifier declared but never used @@ -17,11 +140,11 @@  #  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. -#if defined(BOOST_THREAD_DYN_DLL) +#if defined(BOOST_THREAD_DYN_DLL) && ! defined BOOST_THREAD_DYN_LINK  # define BOOST_THREAD_DYN_LINK  #endif @@ -53,12 +176,18 @@  #if defined(BOOST_HAS_DECLSPEC)  #   if defined(BOOST_THREAD_BUILD_DLL) //Build dll -#       define BOOST_THREAD_DECL __declspec(dllexport) +#       define BOOST_THREAD_DECL BOOST_SYMBOL_EXPORT +//#       define BOOST_THREAD_DECL __declspec(dllexport) +  #   elif defined(BOOST_THREAD_USE_DLL) //Use dll -#       define BOOST_THREAD_DECL __declspec(dllimport) +#       define BOOST_THREAD_DECL BOOST_SYMBOL_IMPORT +//#       define BOOST_THREAD_DECL __declspec(dllimport)  #   else  #       define BOOST_THREAD_DECL  #   endif +#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4) +#  define BOOST_THREAD_DECL BOOST_SYMBOL_VISIBLE +  #else  #   define BOOST_THREAD_DECL  #endif // BOOST_HAS_DECLSPEC @@ -69,7 +198,7 @@  #if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_THREAD_NO_LIB) && !defined(BOOST_THREAD_BUILD_DLL) && !defined(BOOST_THREAD_BUILD_LIB)  //  // Tell the autolink to link dynamically, this will get undef'ed by auto_link.hpp -// once it's done with it:  +// once it's done with it:  //  #if defined(BOOST_THREAD_USE_DLL)  #   define BOOST_DYN_LINK diff --git a/3rdParty/Boost/src/boost/thread/detail/delete.hpp b/3rdParty/Boost/src/boost/thread/detail/delete.hpp new file mode 100644 index 0000000..30e7c93 --- /dev/null +++ b/3rdParty/Boost/src/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_CXX11_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_CXX11_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_CXX11_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/3rdParty/Boost/src/boost/thread/detail/memory.hpp b/3rdParty/Boost/src/boost/thread/detail/memory.hpp new file mode 100644 index 0000000..3c1692d --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/detail/memory.hpp @@ -0,0 +1,156 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (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/config.hpp> +#include <boost/container/allocator_traits.hpp> +#include <boost/container/scoped_allocator.hpp> +#include <boost/type_traits/remove_cv.hpp> +#include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/is_scalar.hpp> +#include <boost/type_traits/is_pointer.hpp> +#include <boost/type_traits/is_same.hpp> +#include <boost/static_assert.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::destroy(alloc_, p); +        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> +  { +  }; + +  template <class Ptr> +  struct pointer_traits +  { +      typedef Ptr pointer; +//      typedef <details> element_type; +//      typedef <details> difference_type; + +//      template <class U> using rebind = <details>; +// +//      static pointer pointer_to(<details>); +  }; + +  template <class T> +  struct pointer_traits<T*> +  { +      typedef T* pointer; +      typedef T element_type; +      typedef ptrdiff_t difference_type; + +//      template <class U> using rebind = U*; +// +//      static pointer pointer_to(<details>) noexcept; +  }; + + +  namespace thread_detail { +    template <class _Ptr1, class _Ptr2, +              bool = is_same<typename remove_cv<typename pointer_traits<_Ptr1>::element_type>::type, +                             typename remove_cv<typename pointer_traits<_Ptr2>::element_type>::type +                            >::value +             > +    struct same_or_less_cv_qualified_imp +        : is_convertible<_Ptr1, _Ptr2> {}; + +    template <class _Ptr1, class _Ptr2> +    struct same_or_less_cv_qualified_imp<_Ptr1, _Ptr2, false> +        : false_type {}; + +    template <class _Ptr1, class _Ptr2, bool = is_scalar<_Ptr1>::value && +                                             !is_pointer<_Ptr1>::value> +    struct same_or_less_cv_qualified +        : same_or_less_cv_qualified_imp<_Ptr1, _Ptr2> {}; + +    template <class _Ptr1, class _Ptr2> +    struct same_or_less_cv_qualified<_Ptr1, _Ptr2, true> +        : false_type {}; + +  } +  template <class T> +  struct BOOST_SYMBOL_VISIBLE default_delete +  { +  #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +    BOOST_SYMBOL_VISIBLE +    BOOST_CONSTEXPR default_delete() = default; +  #else +    BOOST_SYMBOL_VISIBLE +    BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {} +  #endif +    template <class U> +    BOOST_SYMBOL_VISIBLE +    default_delete(const default_delete<U>&, +                  typename enable_if<is_convertible<U*, T*> >::type* = 0) BOOST_NOEXCEPT {} +    BOOST_SYMBOL_VISIBLE +    void operator() (T* ptr) const BOOST_NOEXCEPT +    { +      BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type"); +      delete ptr; +    } +  }; + +  template <class T> +  struct BOOST_SYMBOL_VISIBLE default_delete<T[]> +  { +  public: +  #ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +    BOOST_SYMBOL_VISIBLE +    BOOST_CONSTEXPR default_delete() = default; +  #else +    BOOST_SYMBOL_VISIBLE +    BOOST_CONSTEXPR default_delete() BOOST_NOEXCEPT {} +  #endif +    template <class U> +    BOOST_SYMBOL_VISIBLE +    default_delete(const default_delete<U[]>&, +                   typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) BOOST_NOEXCEPT {} +    template <class U> +    BOOST_SYMBOL_VISIBLE +    void operator() (U* ptr, +                     typename enable_if<thread_detail::same_or_less_cv_qualified<U*, T*> >::type* = 0) const BOOST_NOEXCEPT +    { +      BOOST_STATIC_ASSERT_MSG(sizeof(T) > 0, "default_delete can not delete incomplete type"); +      delete [] ptr; +    } +  }; + +} // namespace boost + + +#endif //  BOOST_THREAD_DETAIL_MEMORY_HPP diff --git a/3rdParty/Boost/src/boost/thread/detail/move.hpp b/3rdParty/Boost/src/boost/thread/detail/move.hpp index eb21107..f2665e6 100644 --- a/3rdParty/Boost/src/boost/thread/detail/move.hpp +++ b/3rdParty/Boost/src/boost/thread/detail/move.hpp @@ -2,21 +2,31 @@  // 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 +#include <boost/thread/detail/config.hpp>  #ifndef BOOST_NO_SFINAE  #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  { +      namespace detail      { +      template <typename T> +      struct has_move_emulation_enabled_aux_dummy_specialization;          template<typename T>          struct thread_move_t          { @@ -39,22 +49,198 @@ namespace boost          };      } +  #ifndef BOOST_NO_SFINAE      template<typename T> -    typename enable_if<boost::is_convertible<T&,detail::thread_move_t<T> >, detail::thread_move_t<T> >::type move(T& t) +    typename enable_if<boost::is_convertible<T&,boost::detail::thread_move_t<T> >, boost::detail::thread_move_t<T> >::type move(T& t)      { -        return detail::thread_move_t<T>(t); +        return boost::detail::thread_move_t<T>(t);      }  #endif -     +      template<typename T> -    detail::thread_move_t<T> move(detail::thread_move_t<T> t) +    boost::detail::thread_move_t<T> move(boost::detail::thread_move_t<T> t)      {          return t;      } -      } +#if ! defined  BOOST_NO_CXX11_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_CXX11_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_CXX11_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_CXX11_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>  #endif diff --git a/3rdParty/Boost/src/boost/thread/detail/platform.hpp b/3rdParty/Boost/src/boost/thread/detail/platform.hpp index 58601b0..1f33b1a 100644 --- a/3rdParty/Boost/src/boost/thread/detail/platform.hpp +++ b/3rdParty/Boost/src/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/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> diff --git a/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp b/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp index 60c0e65..f1a165c 100644 --- a/3rdParty/Boost/src/boost/thread/detail/thread_interruption.hpp +++ b/3rdParty/Boost/src/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;          };      }  } diff --git a/3rdParty/Boost/src/boost/thread/exceptions.hpp b/3rdParty/Boost/src/boost/thread/exceptions.hpp index 2a05b50..08c28d3 100644 --- a/3rdParty/Boost/src/boost/thread/exceptions.hpp +++ b/3rdParty/Boost/src/boost/thread/exceptions.hpp @@ -1,8 +1,9 @@  // Copyright (C) 2001-2003  // William E. Kempf  // Copyright (C) 2007-9 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  // -//  Distributed under the Boost Software License, Version 1.0. (See accompanying  +//  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_EXCEPTIONS_PDM070801_H @@ -18,161 +19,201 @@  #include <string>  #include <stdexcept> +#include <boost/system/system_error.hpp> +#include <boost/system/error_code.hpp> +  #include <boost/config/abi_prefix.hpp>  namespace boost  { -    class thread_interrupted +    class BOOST_SYMBOL_VISIBLE thread_interrupted      {}; -    class thread_exception: -        public std::exception +    class BOOST_SYMBOL_VISIBLE thread_exception: +        public system::system_error +        //public std::exception      { -    protected: -        thread_exception(): -            m_sys_err(0) +          typedef system::system_error base_type; +    public: +        thread_exception() +          : base_type(0,system::system_category())          {} -     -        thread_exception(int sys_err_code): -            m_sys_err(sys_err_code) + +        thread_exception(int sys_error_code) +          : base_type(sys_error_code, system::system_category())          {} -     -    public: +        thread_exception( int ev, const char * what_arg ) +        : base_type(system::error_code(ev, system::system_category()), what_arg) +        { +        } +        thread_exception( int ev, const std::string & what_arg ) +        : base_type(system::error_code(ev, system::system_category()), what_arg) +        { +        } +          ~thread_exception() throw()          {} -     +          int native_error() const          { -            return m_sys_err; +            return code().value();          } -     -    private: -        int m_sys_err;      }; -    class condition_error: -        public std::exception +    class BOOST_SYMBOL_VISIBLE condition_error: +        public system::system_error +        //public std::exception      { +          typedef system::system_error base_type;      public: -        const char* what() const throw() -        { -            return "Condition error"; -        } +          condition_error() +          : base_type(system::error_code(0, system::system_category()), "Condition error") +          {} +          condition_error( int ev ) +          : base_type(system::error_code(ev, system::system_category()), "Condition error") +          { +          } +          condition_error( int ev, const char * what_arg ) +          : base_type(system::error_code(ev, system::system_category()), what_arg) +          { +          } +          condition_error( int ev, const std::string & what_arg ) +          : base_type(system::error_code(ev, system::system_category()), what_arg) +          { +          }      }; -     -    class lock_error: + +    class BOOST_SYMBOL_VISIBLE lock_error:          public thread_exception      { +          typedef thread_exception base_type;      public:          lock_error() +        : base_type(0, "boost::lock_error")          {} -     -        lock_error(int sys_err_code): -            thread_exception(sys_err_code) -        {} -     -        ~lock_error() throw() -        {} -     -        virtual const char* what() const throw() +        lock_error( int ev ) +        : base_type(ev, "boost::lock_error") +        { +        } +        lock_error( int ev, const char * what_arg ) +        : base_type(ev, what_arg)          { -            return "boost::lock_error";          } +        lock_error( int ev, const std::string & what_arg ) +        : base_type(ev, what_arg) +        { +        } + +        ~lock_error() throw() +        {} +      }; -    class thread_resource_error: +    class BOOST_SYMBOL_VISIBLE thread_resource_error:          public thread_exception      { +          typedef thread_exception base_type;      public: -        thread_resource_error() -        {} -     -        thread_resource_error(int sys_err_code): -            thread_exception(sys_err_code) -        {} -     +          thread_resource_error() +          : base_type(system::errc::resource_unavailable_try_again, "boost::thread_resource_error") +          {} + +          thread_resource_error( int ev ) +          : base_type(ev, "boost::thread_resource_error") +          { +          } +          thread_resource_error( int ev, const char * what_arg ) +          : base_type(ev, what_arg) +          { +          } +          thread_resource_error( int ev, const std::string & what_arg ) +          : base_type(ev, what_arg) +          { +          } + +          ~thread_resource_error() throw()          {} -     -        virtual const char* what() const throw() -        { -            return "boost::thread_resource_error"; -        } -          }; -    class unsupported_thread_option: +    class BOOST_SYMBOL_VISIBLE unsupported_thread_option:          public thread_exception      { +          typedef thread_exception base_type;      public: -        unsupported_thread_option() -        {} -     -        unsupported_thread_option(int sys_err_code): -            thread_exception(sys_err_code) -        {} -     -        ~unsupported_thread_option() throw() -        {} -     +          unsupported_thread_option() +          : base_type(system::errc::invalid_argument, "boost::unsupported_thread_option") +          {} + +          unsupported_thread_option( int ev ) +          : base_type(ev, "boost::unsupported_thread_option") +          { +          } +          unsupported_thread_option( int ev, const char * what_arg ) +          : base_type(ev, what_arg) +          { +          } +          unsupported_thread_option( int ev, const std::string & what_arg ) +          : base_type(ev, what_arg) +          { +          } -        virtual const char* what() const throw() -        { -            return "boost::unsupported_thread_option"; -        } -          }; -    class invalid_thread_argument: +    class BOOST_SYMBOL_VISIBLE invalid_thread_argument:          public thread_exception      { +          typedef thread_exception base_type;      public:          invalid_thread_argument() +        : base_type(system::errc::invalid_argument, "boost::invalid_thread_argument")          {} -     -        invalid_thread_argument(int sys_err_code): -            thread_exception(sys_err_code) -        {} -     -        ~invalid_thread_argument() throw() -        {} -     -        virtual const char* what() const throw() +        invalid_thread_argument( int ev ) +        : base_type(ev, "boost::invalid_thread_argument") +        { +        } +        invalid_thread_argument( int ev, const char * what_arg ) +        : base_type(ev, what_arg)          { -            return "boost::invalid_thread_argument";          } -     +        invalid_thread_argument( int ev, const std::string & what_arg ) +        : base_type(ev, what_arg) +        { +        } +      }; -    class thread_permission_error: +    class BOOST_SYMBOL_VISIBLE thread_permission_error:          public thread_exception      { +          typedef thread_exception base_type;      public: -        thread_permission_error() -        {} -     -        thread_permission_error(int sys_err_code): -            thread_exception(sys_err_code) -        {} -     -        ~thread_permission_error() throw() -        {} -     +          thread_permission_error() +          : base_type(system::errc::permission_denied, "boost::thread_permission_error") +          {} + +          thread_permission_error( int ev ) +          : base_type(ev, "boost::thread_permission_error") +          { +          } +          thread_permission_error( int ev, const char * what_arg ) +          : base_type(ev, what_arg) +          { +          } +          thread_permission_error( int ev, const std::string & what_arg ) +          : base_type(ev, what_arg) +          { +          } -        virtual const char* what() const throw() -        { -            return "boost::thread_permission_error"; -        } -          };  } // namespace boost diff --git a/3rdParty/Boost/src/boost/thread/future.hpp b/3rdParty/Boost/src/boost/thread/future.hpp index a4b4343..6bf5cf6 100644 --- a/3rdParty/Boost/src/boost/thread/future.hpp +++ b/3rdParty/Boost/src/boost/thread/future.hpp @@ -1,4 +1,5 @@ -//  (C) Copyright 2008-10 Anthony Williams  +//  (C) Copyright 2008-10 Anthony Williams +//  (C) Copyright 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 @@ -6,6 +7,15 @@  #ifndef BOOST_THREAD_FUTURE_HPP  #define BOOST_THREAD_FUTURE_HPP + +#include <boost/thread/detail/config.hpp> + +// boost::thread::future requires exception handling +// due to boost::exception::exception_ptr dependency + +#ifndef BOOST_NO_EXCEPTIONS + +#include <boost/detail/scoped_enum_emulation.hpp>  #include <stdexcept>  #include <boost/thread/detail/move.hpp>  #include <boost/thread/thread_time.hpp> @@ -16,6 +26,8 @@  #include <boost/scoped_ptr.hpp>  #include <boost/type_traits/is_fundamental.hpp>  #include <boost/type_traits/is_convertible.hpp> +#include <boost/type_traits/remove_reference.hpp> +#include <boost/type_traits/remove_cv.hpp>  #include <boost/mpl/if.hpp>  #include <boost/config.hpp>  #include <boost/throw_exception.hpp> @@ -28,59 +40,168 @@  #include <list>  #include <boost/next_prior.hpp>  #include <vector> +#include <boost/system/error_code.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +#include <boost/thread/detail/memory.hpp> +#endif + +#include <boost/utility/result_of.hpp> +#include <boost/thread/thread.hpp> + +#if defined BOOST_THREAD_PROVIDES_FUTURE +#define BOOST_THREAD_FUTURE future +#else +#define BOOST_THREAD_FUTURE unique_future +#endif +  namespace boost  { -    class future_uninitialized: -        public std::logic_error + +  //enum class future_errc +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_errc) +  { +      broken_promise, +      future_already_retrieved, +      promise_already_satisfied, +      no_state +  } +  BOOST_SCOPED_ENUM_DECLARE_END(future_errc) + +  namespace system +  { +    template <> +    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc> : public true_type {}; + +    #ifdef BOOST_NO_CXX11_SCOPED_ENUMS +    template <> +    struct BOOST_SYMBOL_VISIBLE is_error_code_enum<future_errc::enum_type> : public true_type { }; +    #endif +  } + +  //enum class launch +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(launch) +  { +      async = 1, +      deferred = 2, +      any = async | deferred +  } +  BOOST_SCOPED_ENUM_DECLARE_END(launch) + +  //enum class future_status +  BOOST_SCOPED_ENUM_DECLARE_BEGIN(future_status) +  { +      ready, +      timeout, +      deferred +  } +  BOOST_SCOPED_ENUM_DECLARE_END(future_status) + +  BOOST_THREAD_DECL +  const system::error_category& future_category() BOOST_NOEXCEPT; + +  namespace system +  { +    inline +    error_code +    make_error_code(future_errc e) //BOOST_NOEXCEPT +    { +        return error_code(underlying_cast<int>(e), boost::future_category()); +    } + +    inline +    error_condition +    make_error_condition(future_errc e) //BOOST_NOEXCEPT +    { +        return error_condition(underlying_cast<int>(e), future_category()); +    } +  } + +  class BOOST_SYMBOL_VISIBLE future_error +      : public std::logic_error +  { +      system::error_code ec_; +  public: +      future_error(system::error_code ec) +      : logic_error(ec.message()), +        ec_(ec) +      { +      } + +      const system::error_code& code() const BOOST_NOEXCEPT +      { +        return ec_; +      } +      const char* what() const BOOST_THREAD_NOEXCEPT_OR_THROW +      { +        return code().message().c_str(); +      } + +  }; + +    class BOOST_SYMBOL_VISIBLE future_uninitialized: +        public future_error      {      public: -        future_uninitialized(): -            std::logic_error("Future Uninitialized") +        future_uninitialized() : +          future_error(system::make_error_code(future_errc::no_state))          {}      }; -    class broken_promise: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE broken_promise: +        public future_error      {      public:          broken_promise(): -            std::logic_error("Broken promise") +          future_error(system::make_error_code(future_errc::broken_promise))          {}      }; -    class future_already_retrieved: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE future_already_retrieved: +        public future_error      {      public:          future_already_retrieved(): -            std::logic_error("Future already retrieved") +          future_error(system::make_error_code(future_errc::future_already_retrieved))          {}      }; -    class promise_already_satisfied: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE promise_already_satisfied: +        public future_error      {      public:          promise_already_satisfied(): -            std::logic_error("Promise already satisfied") +          future_error(system::make_error_code(future_errc::promise_already_satisfied))          {}      }; -    class task_already_started: -        public std::logic_error +    class BOOST_SYMBOL_VISIBLE task_already_started: +        public future_error      {      public:          task_already_started(): -            std::logic_error("Task already started") +        future_error(system::make_error_code(future_errc::promise_already_satisfied))          {}      }; -    class task_moved: -        public std::logic_error -    { -    public: -        task_moved(): -            std::logic_error("Task moved") -        {} -    }; +        class BOOST_SYMBOL_VISIBLE task_moved: +            public future_error +        { +        public: +            task_moved(): +              future_error(system::make_error_code(future_errc::no_state)) +            {} +        }; + +            class promise_moved: +                public future_error +            { +            public: +                  promise_moved(): +                  future_error(system::make_error_code(future_errc::no_state)) +                {} +            };      namespace future_state      { @@ -93,6 +214,7 @@ namespace boost          {              boost::exception_ptr exception;              bool done; +            bool thread_was_interrupted;              boost::mutex mutex;              boost::condition_variable waiters;              typedef std::list<boost::condition_variable_any*> waiter_list; @@ -100,7 +222,8 @@ namespace boost              boost::function<void()> callback;              future_object_base(): -                done(false) +                done(false), +                thread_was_interrupted(false)              {}              virtual ~future_object_base()              {} @@ -111,7 +234,7 @@ namespace boost                  do_callback(lock);                  return external_waiters.insert(external_waiters.end(),&cv);              } -             +              void remove_external_waiter(waiter_list::iterator it)              {                  boost::lock_guard<boost::mutex> lock(mutex); @@ -132,7 +255,7 @@ namespace boost              struct relocker              {                  boost::unique_lock<boost::mutex>& lock; -                 +                  relocker(boost::unique_lock<boost::mutex>& lock_):                      lock(lock_)                  { @@ -155,7 +278,7 @@ namespace boost                      local_callback();                  }              } -             +              void wait(bool rethrow=true)              { @@ -165,6 +288,10 @@ namespace boost                  {                      waiters.wait(lock);                  } +                if(rethrow && thread_was_interrupted) +                { +                    throw boost::thread_interrupted(); +                }                  if(rethrow && exception)                  {                      boost::rethrow_exception(exception); @@ -185,7 +312,26 @@ namespace boost                  }                  return true;              } -             + +#ifdef BOOST_THREAD_USES_CHRONO + +            template <class Clock, class Duration> +            future_status +            wait_until(const chrono::time_point<Clock, Duration>& abs_time) +            { +              boost::unique_lock<boost::mutex> lock(mutex); +              do_callback(lock); +              while(!done) +              { +                  cv_status const st=waiters.wait_until(lock,abs_time); +                  if(st==cv_status::timeout && !done) +                  { +                    return future_status::timeout; +                  } +              } +              return future_status::ready; +            } +#endif              void mark_exceptional_finish_internal(boost::exception_ptr const& e)              {                  exception=e; @@ -196,16 +342,21 @@ namespace boost                  boost::lock_guard<boost::mutex> lock(mutex);                  mark_exceptional_finish_internal(boost::current_exception());              } - +            void mark_interrupted_finish() +            { +                boost::lock_guard<boost::mutex> lock(mutex); +                thread_was_interrupted=true; +                mark_finished_internal(); +            }              bool has_value()              {                  boost::lock_guard<boost::mutex> lock(mutex); -                return done && !exception; +                return done && !(exception || thread_was_interrupted);              }              bool has_exception()              {                  boost::lock_guard<boost::mutex> lock(mutex); -                return done && exception; +                return done && (exception || thread_was_interrupted);              }              template<typename F,typename U> @@ -213,7 +364,7 @@ namespace boost              {                  callback=boost::bind(f,boost::ref(*u));              } -             +          private:              future_object_base(future_object_base const&);              future_object_base& operator=(future_object_base const&); @@ -223,25 +374,31 @@ namespace boost          struct future_traits          {              typedef boost::scoped_ptr<T> storage_type; -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES              typedef T const& source_reference_type;              struct dummy; -            typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,T&&>::type rvalue_source_type; -            typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,T&&>::type move_dest_type; +            typedef typename boost::mpl::if_<boost::is_fundamental<T>,dummy&,BOOST_THREAD_RV_REF(T)>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::is_fundamental<T>,T,BOOST_THREAD_RV_REF(T)>::type move_dest_type; +#elif defined BOOST_THREAD_USES_MOVE +            typedef T& source_reference_type; +            typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::has_move_emulation_enabled<T>,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;  #else              typedef T& source_reference_type; -            typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T const&>::type rvalue_source_type; -            typedef typename boost::mpl::if_<boost::is_convertible<T&,boost::detail::thread_move_t<T> >,boost::detail::thread_move_t<T>,T>::type move_dest_type; +            typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T const&>::type rvalue_source_type; +            typedef typename boost::mpl::if_<boost::is_convertible<T&,BOOST_THREAD_RV_REF(T) >,BOOST_THREAD_RV_REF(T),T>::type move_dest_type;  #endif +            typedef const T& shared_future_get_result_type; +              static void init(storage_type& storage,source_reference_type t)              {                  storage.reset(new T(t));              } -             +              static void init(storage_type& storage,rvalue_source_type t)              { -                storage.reset(new T(static_cast<rvalue_source_type>(t))); +              storage.reset(new T(static_cast<rvalue_source_type>(t)));              }              static void cleanup(storage_type& storage) @@ -249,7 +406,7 @@ namespace boost                  storage.reset();              }          }; -         +          template<typename T>          struct future_traits<T&>          { @@ -258,6 +415,7 @@ namespace boost              struct rvalue_source_type              {};              typedef T& move_dest_type; +            typedef T& shared_future_get_result_type;              static void init(storage_type& storage,T& t)              { @@ -275,6 +433,7 @@ namespace boost          {              typedef bool storage_type;              typedef void move_dest_type; +            typedef void shared_future_get_result_type;              static void init(storage_type& storage)              { @@ -296,7 +455,8 @@ namespace boost              typedef typename future_traits<T>::source_reference_type source_reference_type;              typedef typename future_traits<T>::rvalue_source_type rvalue_source_type;              typedef typename future_traits<T>::move_dest_type move_dest_type; -             +            typedef typename future_traits<T>::shared_future_get_result_type shared_future_get_result_type; +              storage_type result;              future_object(): @@ -308,6 +468,7 @@ namespace boost                  future_traits<T>::init(result,result_);                  mark_finished_internal();              } +              void mark_finished_with_result_internal(rvalue_source_type result_)              {                  future_traits<T>::init(result,static_cast<rvalue_source_type>(result_)); @@ -319,10 +480,11 @@ namespace boost                  boost::lock_guard<boost::mutex> lock(mutex);                  mark_finished_with_result_internal(result_);              } +              void mark_finished_with_result(rvalue_source_type result_)              {                  boost::lock_guard<boost::mutex> lock(mutex); -                mark_finished_with_result_internal(result_); +                mark_finished_with_result_internal(static_cast<rvalue_source_type>(result_));              }              move_dest_type get() @@ -331,6 +493,12 @@ namespace boost                  return static_cast<move_dest_type>(*result);              } +            shared_future_get_result_type get_sh() +            { +                wait(); +                return static_cast<shared_future_get_result_type>(*result); +            } +              future_state::state get_state()              {                  boost::lock_guard<boost::mutex> guard(mutex); @@ -353,6 +521,8 @@ namespace boost          struct future_object<void>:              detail::future_object_base          { +          typedef void shared_future_get_result_type; +              future_object()              {} @@ -371,7 +541,10 @@ namespace boost              {                  wait();              } -             +            void get_sh() +            { +                wait(); +            }              future_state::state get_state()              {                  boost::lock_guard<boost::mutex> guard(mutex); @@ -384,74 +557,93 @@ namespace boost                      return future_state::ready;                  }              } -          private:              future_object(future_object const&);              future_object& operator=(future_object const&);          }; +//        template<typename T, typename Allocator> +//        struct future_object_alloc: public future_object<T> +//        { +//          typedef future_object<T> base; +//          Allocator alloc_; +// +//        public: +//          explicit future_object_alloc(const Allocator& a) +//              : alloc_(a) {} +// +//        };          class future_waiter          {              struct registered_waiter; -            typedef std::vector<registered_waiter>::size_type count_type; -             +            typedef std::vector<int>::size_type count_type; +              struct registered_waiter              { -                boost::shared_ptr<detail::future_object_base> future; +                boost::shared_ptr<detail::future_object_base> future_;                  detail::future_object_base::waiter_list::iterator wait_iterator;                  count_type index; -                registered_waiter(boost::shared_ptr<detail::future_object_base> const& future_, +                registered_waiter(boost::shared_ptr<detail::future_object_base> const& a_future,                                    detail::future_object_base::waiter_list::iterator wait_iterator_,                                    count_type index_): -                    future(future_),wait_iterator(wait_iterator_),index(index_) +                    future_(a_future),wait_iterator(wait_iterator_),index(index_)                  {}              }; -             +              struct all_futures_lock              { -                count_type count; +#ifdef _MANAGED +                typedef std::ptrdiff_t count_type_portable; +#else +                typedef count_type count_type_portable; +#endif +                count_type_portable count;                  boost::scoped_array<boost::unique_lock<boost::mutex> > locks; -                 +                  all_futures_lock(std::vector<registered_waiter>& futures):                      count(futures.size()),locks(new boost::unique_lock<boost::mutex>[count])                  { -                    for(count_type i=0;i<count;++i) +                    for(count_type_portable i=0;i<count;++i)                      { -                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future->mutex); +#if defined __DECCXX || defined __SUNPRO_CC || defined __hpux +                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex).move(); +#else +                        locks[i]=boost::unique_lock<boost::mutex>(futures[i].future_->mutex); +#endif                      }                  } -                 +                  void lock()                  {                      boost::lock(locks.get(),locks.get()+count);                  } -                 +                  void unlock()                  { -                    for(count_type i=0;i<count;++i) +                    for(count_type_portable i=0;i<count;++i)                      {                          locks[i].unlock();                      }                  }              }; -             +              boost::condition_variable_any cv;              std::vector<registered_waiter> futures;              count_type future_count; -             +          public:              future_waiter():                  future_count(0)              {} -             +              template<typename F>              void add(F& f)              { -                if(f.future) +                if(f.future_)                  { -                    futures.push_back(registered_waiter(f.future,f.future->register_external_waiter(cv),future_count)); +                    futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count));                  }                  ++future_count;              } @@ -463,7 +655,7 @@ namespace boost                  {                      for(count_type i=0;i<futures.size();++i)                      { -                        if(futures[i].future->done) +                        if(futures[i].future_->done)                          {                              return futures[i].index;                          } @@ -471,21 +663,21 @@ namespace boost                      cv.wait(lk);                  }              } -             +              ~future_waiter()              {                  for(count_type i=0;i<futures.size();++i)                  { -                    futures[i].future->remove_external_waiter(futures[i].wait_iterator); +                    futures[i].future_->remove_external_waiter(futures[i].wait_iterator);                  }              } -             +          }; -         +      }      template <typename R> -    class unique_future; +    class BOOST_THREAD_FUTURE;      template <typename R>      class shared_future; @@ -495,13 +687,13 @@ namespace boost      {          BOOST_STATIC_CONSTANT(bool, value=false);      }; -     +      template<typename T> -    struct is_future_type<unique_future<T> > +    struct is_future_type<BOOST_THREAD_FUTURE<T> >      {          BOOST_STATIC_CONSTANT(bool, value=true);      }; -     +      template<typename T>      struct is_future_type<shared_future<T> >      { @@ -531,7 +723,7 @@ namespace boost          f2.wait();          f3.wait();      } -     +      template<typename F1,typename F2,typename F3,typename F4>      void wait_for_all(F1& f1,F2& f2,F3& f3,F4& f4)      { @@ -556,7 +748,7 @@ namespace boost      {          if(begin==end)              return end; -         +          detail::future_waiter waiter;          for(Iterator current=begin;current!=end;++current)          { @@ -583,7 +775,7 @@ namespace boost          waiter.add(f3);          return waiter.wait();      } -     +      template<typename F1,typename F2,typename F3,typename F4>      unsigned wait_for_any(F1& f1,F2& f2,F3& f3,F4& f4)      { @@ -606,7 +798,7 @@ namespace boost          waiter.add(f5);          return waiter.wait();      } -     +      template <typename R>      class promise; @@ -614,14 +806,13 @@ namespace boost      class packaged_task;      template <typename R> -    class unique_future +    class BOOST_THREAD_FUTURE      { -        unique_future(unique_future & rhs);// = delete; -        unique_future& operator=(unique_future& rhs);// = delete; +    private:          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          friend class shared_future<R>;          friend class promise<R>; @@ -630,139 +821,151 @@ namespace boost          typedef typename detail::future_traits<R>::move_dest_type move_dest_type; -        unique_future(future_ptr future_): -            future(future_) +        BOOST_THREAD_FUTURE(future_ptr a_future): +            future_(a_future)          {}      public: +        BOOST_THREAD_MOVABLE_ONLY(BOOST_THREAD_FUTURE)          typedef future_state::state state; -        unique_future() +        BOOST_THREAD_FUTURE()          {} -        -        ~unique_future() + +        ~BOOST_THREAD_FUTURE()          {} -#ifndef BOOST_NO_RVALUE_REFERENCES -        unique_future(unique_future && other) -        { -            future.swap(other.future); -        } -        unique_future& operator=(unique_future && other) -        { -            future=other.future; -            other.future.reset(); -            return *this; -        } -#else -        unique_future(boost::detail::thread_move_t<unique_future> other): -            future(other->future) +        BOOST_THREAD_FUTURE(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT: +            future_(BOOST_THREAD_RV(other).future_)          { -            other->future.reset(); +            BOOST_THREAD_RV(other).future_.reset();          } -        unique_future& operator=(boost::detail::thread_move_t<unique_future> other) +        BOOST_THREAD_FUTURE& operator=(BOOST_THREAD_RV_REF(BOOST_THREAD_FUTURE) other) BOOST_NOEXCEPT          { -            future=other->future; -            other->future.reset(); +            future_=BOOST_THREAD_RV(other).future_; +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -        operator boost::detail::thread_move_t<unique_future>() +        shared_future<R> share()          { -            return boost::detail::thread_move_t<unique_future>(*this); +          return shared_future<R>(::boost::move(*this));          } -#endif -        void swap(unique_future& other) +        void swap(BOOST_THREAD_FUTURE& other)          { -            future.swap(other.future); +            future_.swap(other.future_);          }          // retrieving the value          move_dest_type get()          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->get(); +            return future_->get();          } -         +          // functions to check state, and wait for ready -        state get_state() const +        state get_state() const BOOST_NOEXCEPT          { -            if(!future) +            if(!future_)              {                  return future_state::uninitialized;              } -            return future->get_state(); +            return future_->get_state();          } -         -        bool is_ready() const +        bool is_ready() const BOOST_NOEXCEPT          {              return get_state()==future_state::ready;          } -         -        bool has_exception() const + +        bool has_exception() const BOOST_NOEXCEPT          { -            return future && future->has_exception(); +            return future_ && future_->has_exception();          } -         -        bool has_value() const + +        bool has_value() const BOOST_NOEXCEPT          { -            return future && future->has_value(); +            return future_ && future_->has_value();          } -         + +        bool valid() const BOOST_NOEXCEPT +        { +            return future_ != 0; +        } + +          void wait() const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            future->wait(false); +            future_->wait(false);          } -         +          template<typename Duration>          bool timed_wait(Duration const& rel_time) const          {              return timed_wait_until(boost::get_system_time()+rel_time);          } -         +          bool timed_wait_until(boost::system_time const& abs_time) const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->timed_wait_until(abs_time); +            return future_->timed_wait_until(abs_time);          } -         +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        future_status +        wait_for(const chrono::duration<Rep, Period>& rel_time) const +        { +          return wait_until(chrono::steady_clock::now() + rel_time); + +        } +        template <class Clock, class Duration> +        future_status +        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const +        { +          if(!future_) +          { +              boost::throw_exception(future_uninitialized()); +          } +          return future_->wait_until(abs_time); +        } +#endif      }; +    BOOST_THREAD_DCL_MOVABLE_BEG(T) BOOST_THREAD_FUTURE<T> BOOST_THREAD_DCL_MOVABLE_END +      template <typename R>      class shared_future      {          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; -//         shared_future(const unique_future<R>& other); -//         shared_future& operator=(const unique_future<R>& other); +        future_ptr future_;          friend class detail::future_waiter;          friend class promise<R>;          friend class packaged_task<R>; -         -        shared_future(future_ptr future_): -            future(future_) + +        shared_future(future_ptr a_future): +            future_(a_future)          {}      public: +        BOOST_THREAD_MOVABLE(shared_future) +          shared_future(shared_future const& other): -            future(other.future) +            future_(other.future_)          {}          typedef future_state::state state; @@ -775,396 +978,405 @@ namespace boost          shared_future& operator=(shared_future const& other)          { -            future=other.future; +            future_=other.future_;              return *this;          } -#ifndef BOOST_NO_RVALUE_REFERENCES -        shared_future(shared_future && other) +        shared_future(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(other).future_)          { -            future.swap(other.future); +            BOOST_THREAD_RV(other).future_.reset();          } -        shared_future(unique_future<R> && other) +        shared_future(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(other).future_)          { -            future.swap(other.future); +            BOOST_THREAD_RV(other).future_.reset();          } -        shared_future& operator=(shared_future && other) +        shared_future& operator=(BOOST_THREAD_RV_REF(shared_future) other) BOOST_NOEXCEPT          { -            future.swap(other.future); -            other.future.reset(); +            future_.swap(BOOST_THREAD_RV(other).future_); +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -        shared_future& operator=(unique_future<R> && other) +        shared_future& operator=(BOOST_THREAD_RV_REF_BEG BOOST_THREAD_FUTURE<R> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT          { -            future.swap(other.future); -            other.future.reset(); +            future_.swap(BOOST_THREAD_RV(other).future_); +            BOOST_THREAD_RV(other).future_.reset();              return *this;          } -#else             -        shared_future(boost::detail::thread_move_t<shared_future> other): -            future(other->future) -        { -            other->future.reset(); -        } -//         shared_future(const unique_future<R> &) = delete; -        shared_future(boost::detail::thread_move_t<unique_future<R> > other): -            future(other->future) -        { -            other->future.reset(); -        } -        shared_future& operator=(boost::detail::thread_move_t<shared_future> other) -        { -            future.swap(other->future); -            other->future.reset(); -            return *this; -        } -        shared_future& operator=(boost::detail::thread_move_t<unique_future<R> > other) -        { -            future.swap(other->future); -            other->future.reset(); -            return *this; -        } - -        operator boost::detail::thread_move_t<shared_future>() -        { -            return boost::detail::thread_move_t<shared_future>(*this); -        } - -#endif -        void swap(shared_future& other) +        void swap(shared_future& other) BOOST_NOEXCEPT          { -            future.swap(other.future); +            future_.swap(other.future_);          }          // retrieving the value -        R get() +        typename detail::future_object<R>::shared_future_get_result_type get()          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->get(); +            return future_->get_sh();          } -         +          // functions to check state, and wait for ready -        state get_state() const +        state get_state() const  BOOST_NOEXCEPT          { -            if(!future) +            if(!future_)              {                  return future_state::uninitialized;              } -            return future->get_state(); +            return future_->get_state();          } -         -        bool is_ready() const +        bool valid() const  BOOST_NOEXCEPT +        { +            return future_ != 0; +        } + +        bool is_ready() const  BOOST_NOEXCEPT          {              return get_state()==future_state::ready;          } -         -        bool has_exception() const + +        bool has_exception() const BOOST_NOEXCEPT          { -            return future && future->has_exception(); +            return future_ && future_->has_exception();          } -         -        bool has_value() const + +        bool has_value() const BOOST_NOEXCEPT          { -            return future && future->has_value(); +            return future_ && future_->has_value();          }          void wait() const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            future->wait(false); +            future_->wait(false);          } -         +          template<typename Duration>          bool timed_wait(Duration const& rel_time) const          {              return timed_wait_until(boost::get_system_time()+rel_time);          } -         +          bool timed_wait_until(boost::system_time const& abs_time) const          { -            if(!future) +            if(!future_)              {                  boost::throw_exception(future_uninitialized());              } -            return future->timed_wait_until(abs_time); +            return future_->timed_wait_until(abs_time);          } -         +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Rep, class Period> +        future_status +        wait_for(const chrono::duration<Rep, Period>& rel_time) const +        { +          return wait_until(chrono::steady_clock::now() + rel_time); + +        } +        template <class Clock, class Duration> +        future_status +        wait_until(const chrono::time_point<Clock, Duration>& abs_time) const +        { +          if(!future_) +          { +              boost::throw_exception(future_uninitialized()); +          } +          return future_->wait_until(abs_time); +        } +#endif      }; +    BOOST_THREAD_DCL_MOVABLE_BEG(T) shared_future<T> BOOST_THREAD_DCL_MOVABLE_END +      template <typename R>      class promise      {          typedef boost::shared_ptr<detail::future_object<R> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          bool future_obtained; -         -        promise(promise & rhs);// = delete; -        promise & operator=(promise & rhs);// = delete;          void lazy_init()          { -            if(!atomic_load(&future)) +#if defined BOOST_THREAD_PROMISE_LAZY +            if(!atomic_load(&future_))              {                  future_ptr blank; -                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<R>)); +                atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<R>));              } +#endif          } -         +      public: -//         template <class Allocator> explicit promise(Allocator a); +        BOOST_THREAD_MOVABLE_ONLY(promise) +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        promise(boost::allocator_arg_t, Allocator a) +        { +          typedef typename Allocator::template rebind<detail::future_object<R> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          future_ = future_ptr(::new(a2.allocate(1)) detail::future_object<R>(), D(a2, 1) ); +          future_obtained = false; +        } +#endif          promise(): -            future(),future_obtained(false) +#if defined BOOST_THREAD_PROMISE_LAZY +            future_(), +#else +            future_(new detail::future_object<R>()), +#endif +            future_obtained(false)          {} -         +          ~promise()          { -            if(future) +            if(future_)              { -                boost::lock_guard<boost::mutex> lock(future->mutex); +                boost::lock_guard<boost::mutex> lock(future_->mutex); -                if(!future->done) +                if(!future_->done)                  { -                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); +                    future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));                  }              }          }          // Assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        promise(promise && rhs): -            future_obtained(rhs.future_obtained) +        promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)          { -            future.swap(rhs.future); -            rhs.future_obtained=false; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;          } -        promise & operator=(promise&& rhs) +        promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT          { -            future.swap(rhs.future); -            future_obtained=rhs.future_obtained; -            rhs.future.reset(); -            rhs.future_obtained=false; -            return *this; -        } -#else -        promise(boost::detail::thread_move_t<promise> rhs): -            future(rhs->future),future_obtained(rhs->future_obtained) -        { -            rhs->future.reset(); -            rhs->future_obtained=false; -        } -        promise & operator=(boost::detail::thread_move_t<promise> rhs) -        { -            future=rhs->future; -            future_obtained=rhs->future_obtained; -            rhs->future.reset(); -            rhs->future_obtained=false; +            future_=BOOST_THREAD_RV(rhs).future_; +            future_obtained=BOOST_THREAD_RV(rhs).future_obtained; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;              return *this;          } -        operator boost::detail::thread_move_t<promise>() -        { -            return boost::detail::thread_move_t<promise>(*this); -        } -#endif    -                  void swap(promise& other)          { -            future.swap(other.future); +            future_.swap(other.future_);              std::swap(future_obtained,other.future_obtained);          }          // Result retrieval -        unique_future<R> get_future() +        BOOST_THREAD_FUTURE<R> get_future()          {              lazy_init(); -            if(future_obtained) +            if (future_.get()==0) +            { +                boost::throw_exception(promise_moved()); +            } +            if (future_obtained)              {                  boost::throw_exception(future_already_retrieved());              }              future_obtained=true; -            return unique_future<R>(future); +            return BOOST_THREAD_FUTURE<R>(future_);          }          void set_value(typename detail::future_traits<R>::source_reference_type r)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(r); +            future_->mark_finished_with_result_internal(r);          }  //         void set_value(R && r);          void set_value(typename detail::future_traits<R>::rvalue_source_type r)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r)); +            future_->mark_finished_with_result_internal(static_cast<typename detail::future_traits<R>::rvalue_source_type>(r));          }          void set_exception(boost::exception_ptr p)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_exceptional_finish_internal(p); +            future_->mark_exceptional_finish_internal(p);          } +        // setting the result with deferred notification +        //void set_value_at_thread_exit(const R& r); // NOT YET IMPLEMENTED +        //void set_value_at_thread_exit(see below); // NOT YET IMPLEMENTED +        //void set_exception_at_thread_exit(exception_ptr p); // NOT YET IMPLEMENTED +          template<typename F>          void set_wait_callback(F f)          {              lazy_init(); -            future->set_wait_callback(f,this); +            future_->set_wait_callback(f,this);          } -         +      };      template <>      class promise<void>      {          typedef boost::shared_ptr<detail::future_object<void> > future_ptr; -         -        future_ptr future; + +        future_ptr future_;          bool future_obtained; -         -        promise(promise & rhs);// = delete; -        promise & operator=(promise & rhs);// = delete;          void lazy_init()          { -            if(!atomic_load(&future)) +#if defined BOOST_THREAD_PROMISE_LAZY +            if(!atomic_load(&future_))              {                  future_ptr blank; -                atomic_compare_exchange(&future,&blank,future_ptr(new detail::future_object<void>)); +                atomic_compare_exchange(&future_,&blank,future_ptr(new detail::future_object<void>));              } +#endif          }      public: -//         template <class Allocator> explicit promise(Allocator a); +        BOOST_THREAD_MOVABLE_ONLY(promise) + +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        promise(boost::allocator_arg_t, Allocator a) +        { +          typedef typename Allocator::template rebind<detail::future_object<void> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          future_ = future_ptr(::new(a2.allocate(1)) detail::future_object<void>(), D(a2, 1) ); +          future_obtained = false; +        } +#endif          promise(): -            future(),future_obtained(false) +#if defined BOOST_THREAD_PROMISE_LAZY +            future_(), +#else +            future_(new detail::future_object<void>), +#endif +            future_obtained(false)          {} -         +          ~promise()          { -            if(future) +            if(future_)              { -                boost::lock_guard<boost::mutex> lock(future->mutex); +                boost::lock_guard<boost::mutex> lock(future_->mutex); -                if(!future->done) +                if(!future_->done)                  { -                    future->mark_exceptional_finish_internal(boost::copy_exception(broken_promise())); +                    future_->mark_exceptional_finish_internal(boost::copy_exception(broken_promise()));                  }              }          }          // Assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        promise(promise && rhs): -            future_obtained(rhs.future_obtained) -        { -            future.swap(rhs.future); -            rhs.future_obtained=false; -        } -        promise & operator=(promise&& rhs) +        promise(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT : +            future_(BOOST_THREAD_RV(rhs).future_),future_obtained(BOOST_THREAD_RV(rhs).future_obtained)          { -            future.swap(rhs.future); -            future_obtained=rhs.future_obtained; -            rhs.future.reset(); -            rhs.future_obtained=false; -            return *this; -        } -#else -        promise(boost::detail::thread_move_t<promise> rhs): -            future(rhs->future),future_obtained(rhs->future_obtained) -        { -            rhs->future.reset(); -            rhs->future_obtained=false; +          // we need to release the future as shared_ptr doesn't implements move semantics +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;          } -        promise & operator=(boost::detail::thread_move_t<promise> rhs) + +        promise & operator=(BOOST_THREAD_RV_REF(promise) rhs) BOOST_NOEXCEPT          { -            future=rhs->future; -            future_obtained=rhs->future_obtained; -            rhs->future.reset(); -            rhs->future_obtained=false; +            future_=BOOST_THREAD_RV(rhs).future_; +            future_obtained=BOOST_THREAD_RV(rhs).future_obtained; +            BOOST_THREAD_RV(rhs).future_.reset(); +            BOOST_THREAD_RV(rhs).future_obtained=false;              return *this;          } -        operator boost::detail::thread_move_t<promise>() -        { -            return boost::detail::thread_move_t<promise>(*this); -        } -#endif -                  void swap(promise& other)          { -            future.swap(other.future); +            future_.swap(other.future_);              std::swap(future_obtained,other.future_obtained);          }          // Result retrieval -        unique_future<void> get_future() +        BOOST_THREAD_FUTURE<void> get_future()          {              lazy_init(); -             + +            if (future_.get()==0) +            { +                boost::throw_exception(promise_moved()); +            }              if(future_obtained)              {                  boost::throw_exception(future_already_retrieved());              }              future_obtained=true; -            return unique_future<void>(future); +            return BOOST_THREAD_FUTURE<void>(future_);          }          void set_value()          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_finished_with_result_internal(); +            future_->mark_finished_with_result_internal();          }          void set_exception(boost::exception_ptr p)          {              lazy_init(); -            boost::lock_guard<boost::mutex> lock(future->mutex); -            if(future->done) +            boost::lock_guard<boost::mutex> lock(future_->mutex); +            if(future_->done)              {                  boost::throw_exception(promise_already_satisfied());              } -            future->mark_exceptional_finish_internal(p); +            future_->mark_exceptional_finish_internal(p);          }          template<typename F>          void set_wait_callback(F f)          {              lazy_init(); -            future->set_wait_callback(f,this); +            future_->set_wait_callback(f,this);          } -         +      }; +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +    namespace container +    { +      template <class R, class Alloc> +      struct uses_allocator<promise<R> , Alloc> : true_type +      { +      }; +    } +#endif + +    BOOST_THREAD_DCL_MOVABLE_BEG(T) promise<T> BOOST_THREAD_DCL_MOVABLE_END +      namespace detail      {          template<typename R> @@ -1177,6 +1389,10 @@ namespace boost                  started(false)              {} +            void reset() +            { +              started=false; +            }              void run()              {                  { @@ -1199,30 +1415,44 @@ namespace boost                      this->mark_exceptional_finish_internal(boost::copy_exception(boost::broken_promise()));                  }              } -             -             + +              virtual void do_run()=0;          }; -         -         + + + +          template<typename R,typename F>          struct task_object:              task_base<R>          { +        private: +          task_object(task_object&); +        public:              F f;              task_object(F const& f_):                  f(f_)              {} -            task_object(boost::detail::thread_move_t<F> f_): -                f(f_) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +            task_object(BOOST_THREAD_RV_REF(F) f_): +              f(boost::forward<F>(f_)) +            {} +#else +            task_object(BOOST_THREAD_RV_REF(F) f_): +                f(boost::move(f_))              {} -             +#endif              void do_run()              {                  try                  {                      this->mark_finished_with_result(f());                  } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                }                  catch(...)                  {                      this->mark_exceptional_finish(); @@ -1230,18 +1460,55 @@ namespace boost              }          }; +            template<typename R> +            struct task_object<R,R (*)()>: +                task_base<R> +            { +            private: +              task_object(task_object&); +            public: +                R (*f)(); +                task_object(R (*f_)()): +                    f(f_) +                {} +                void do_run() +                { +                    try +                    { +                        this->mark_finished_with_result(f()); +                    } +                    catch(thread_interrupted& ) +                    { +                        this->mark_interrupted_finish(); +                    } +                    catch(...) +                    { +                        this->mark_exceptional_finish(); +                    } +                } +            }; +          template<typename F>          struct task_object<void,F>:              task_base<void>          { +        private: +          task_object(task_object&); +        public:              F f;              task_object(F const& f_):                  f(f_)              {} -            task_object(boost::detail::thread_move_t<F> f_): -                f(f_) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +            task_object(BOOST_THREAD_RV_REF(F) f_): +              f(boost::forward<F>(f_))              {} -             +#else +            task_object(BOOST_THREAD_RV_REF(F) f_): +                f(boost::move(f_)) +            {} +#endif +              void do_run()              {                  try @@ -1249,6 +1516,39 @@ namespace boost                      f();                      this->mark_finished_with_result();                  } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                } +                catch(...) +                { +                    this->mark_exceptional_finish(); +                } +            } +        }; + +        template<> +        struct task_object<void,void (*)()>: +            task_base<void> +        { +        private: +          task_object(task_object&); +        public: +            void (*f)(); +            task_object(void (*f_)()): +                f(f_) +            {} +            void do_run() +            { +                try +                { +                  f(); +                  this->mark_finished_with_result(); +                } +                catch(thread_interrupted& ) +                { +                    this->mark_interrupted_finish(); +                }                  catch(...)                  {                      this->mark_exceptional_finish(); @@ -1257,41 +1557,92 @@ namespace boost          };      } -          template<typename R>      class packaged_task      { +        typedef boost::shared_ptr<detail::task_base<R> > task_ptr;          boost::shared_ptr<detail::task_base<R> > task;          bool future_obtained; -        packaged_task(packaged_task&);// = delete; -        packaged_task& operator=(packaged_task&);// = delete; -              public: +        typedef R result_type; +        BOOST_THREAD_MOVABLE_ONLY(packaged_task) +          packaged_task():              future_obtained(false)          {} -         +          // construction and destruction -        template <class F> -        explicit packaged_task(F const& f): -            task(new detail::task_object<R,F>(f)),future_obtained(false) -        {} +          explicit packaged_task(R(*f)()):              task(new detail::task_object<R,R(*)()>(f)),future_obtained(false)          {} -         +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +        template <class F> +        explicit packaged_task(BOOST_THREAD_RV_REF(F) f): +            task(new detail::task_object<R, +                typename remove_cv<typename remove_reference<F>::type>::type +                >(boost::forward<F>(f))),future_obtained(false) +        {} +#else          template <class F> -        explicit packaged_task(boost::detail::thread_move_t<F> f): +        explicit packaged_task(F const& f):              task(new detail::task_object<R,F>(f)),future_obtained(false)          {} +        template <class F> +        explicit packaged_task(BOOST_THREAD_RV_REF(F) f): +            task(new detail::task_object<R,F>(boost::move(f))),future_obtained(false) +        {} +#endif -//         template <class F, class Allocator> -//         explicit packaged_task(F const& f, Allocator a); -//         template <class F, class Allocator> -//         explicit packaged_task(F&& f, Allocator a); +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +        template <class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, R(*f)()) +        { +          typedef R(*FR)(); +          typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,FR>(f), D(a2, 1) ); +          future_obtained = false; +        } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f) +        { +          typedef typename remove_cv<typename remove_reference<F>::type>::type FR; +          typedef typename Allocator::template rebind<detail::task_object<R,FR> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,FR>(boost::forward<F>(f)), D(a2, 1) ); +          future_obtained = false; +        } +#else +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, const F& f) +        { +          typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,F>(f), D(a2, 1) ); +          future_obtained = false; +        } +        template <class F, class Allocator> +        packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f) +        { +          typedef typename Allocator::template rebind<detail::task_object<R,F> >::other A2; +          A2 a2(a); +          typedef thread_detail::allocator_destructor<A2> D; + +          task = task_ptr(::new(a2.allocate(1)) detail::task_object<R,F>(boost::move(f)), D(a2, 1) ); +          future_obtained = false; +        } +#endif //BOOST_NO_CXX11_RVALUE_REFERENCES +#endif // BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS          ~packaged_task()          { @@ -1302,46 +1653,39 @@ namespace boost          }          // assignment -#ifndef BOOST_NO_RVALUE_REFERENCES -        packaged_task(packaged_task&& other): -            future_obtained(other.future_obtained) +        packaged_task(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT : +            future_obtained(BOOST_THREAD_RV(other).future_obtained)          { -            task.swap(other.task); -            other.future_obtained=false; +            task.swap(BOOST_THREAD_RV(other).task); +            BOOST_THREAD_RV(other).future_obtained=false;          } -        packaged_task& operator=(packaged_task&& other) +        packaged_task& operator=(BOOST_THREAD_RV_REF(packaged_task) other) BOOST_NOEXCEPT          { -            packaged_task temp(static_cast<packaged_task&&>(other)); +            packaged_task temp(static_cast<BOOST_THREAD_RV_REF(packaged_task)>(other));              swap(temp);              return *this;          } -#else -        packaged_task(boost::detail::thread_move_t<packaged_task> other): -            future_obtained(other->future_obtained) -        { -            task.swap(other->task); -            other->future_obtained=false; -        } -        packaged_task& operator=(boost::detail::thread_move_t<packaged_task> other) -        { -            packaged_task temp(other); -            swap(temp); -            return *this; -        } -        operator boost::detail::thread_move_t<packaged_task>() + +        void reset()          { -            return boost::detail::thread_move_t<packaged_task>(*this); +            if (!valid()) +                throw future_error(system::make_error_code(future_errc::no_state)); +            task->reset(); +            future_obtained=false;          } -#endif -        void swap(packaged_task& other) +        void swap(packaged_task& other) BOOST_NOEXCEPT          {              task.swap(other.task);              std::swap(future_obtained,other.future_obtained);          } +        bool valid() const BOOST_NOEXCEPT +        { +          return task.get()!=0; +        }          // result retrieval -        unique_future<R> get_future() +        BOOST_THREAD_FUTURE<R> get_future()          {              if(!task)              { @@ -1350,14 +1694,16 @@ namespace boost              else if(!future_obtained)              {                  future_obtained=true; -                return unique_future<R>(task); +                return BOOST_THREAD_FUTURE<R>(task);              }              else              {                  boost::throw_exception(future_already_retrieved());              } +            return BOOST_THREAD_FUTURE<R>(); +          } -         +          // execution          void operator()() @@ -1374,10 +1720,149 @@ namespace boost          {              task->set_wait_callback(f,this);          } -         +      }; -} +#if defined BOOST_THREAD_PROVIDES_FUTURE_CTOR_ALLOCATORS +    namespace container +    { +      template <class R, class Alloc> +      struct uses_allocator<packaged_task<R>, Alloc> +        : public true_type {}; +    } +#endif + +    BOOST_THREAD_DCL_MOVABLE_BEG(T) packaged_task<T> BOOST_THREAD_DCL_MOVABLE_END + + +        template <class R> +        BOOST_THREAD_FUTURE<R> +        async(launch policy, R(*f)()) +        { +            if (int(policy) & int(launch::async)) +            { +              packaged_task<R> pt( f ); + +              BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +              boost::thread( boost::move(pt) ).detach(); +              return ::boost::move(ret); +            } +            else if (int(policy) & int(launch::deferred)) +            { +              packaged_task<R> pt( f ); +              BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +              return ::boost::move(ret); +            } else { +              BOOST_THREAD_FUTURE<R> ret; +              return ::boost::move(ret); +            } +        } + +        template <class R> +        BOOST_THREAD_FUTURE<R> +        async(R(*f)()) +        { +            return async(launch::any, f); +        } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +    async(launch policy, BOOST_THREAD_FWD_REF(F)  f) +    { +        typedef typename boost::result_of<typename decay<F>::type()>::type R; +        if (int(policy) & int(launch::async)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          boost::thread( boost::move(pt) ).detach(); +          return ::boost::move(ret); +        } +        else if (int(policy) & int(launch::deferred)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          return ::boost::move(ret); +        } else { +          BOOST_THREAD_FUTURE<R> ret; +          return ::boost::move(ret); +        } +    } +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +    async(BOOST_THREAD_RV_REF(F) f) +    { +        return async(launch::any, boost::forward<F>(f)); +    } +#else + +//    template <class F> +//    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +//    async(launch policy, F const& f) +//    { +//        typedef typename boost::result_of<typename decay<F>::type()>::type R; +//        if (int(policy) & int(launch::async)) +//        { +//          packaged_task<R> pt( f ); +// +//          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +//          boost::thread( boost::move(pt) ).detach(); +//          return ::boost::move(ret); +//        } +//        else if (int(policy) & int(launch::deferred)) +//        { +//          packaged_task<R> pt( f ); +// +//          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +//          return ::boost::move(ret); +//        } else { +//          BOOST_THREAD_FUTURE<R> ret; +//          return ::boost::move(ret); +//        } +//    } +//    template <class F> +//    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +//    async(F const& f) +//    { +//        return async(launch::any, f); +//    } + +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<typename decay<F>::type()>::type> +    async(launch policy, BOOST_THREAD_FWD_REF(F)  f) +    { +        typedef typename boost::result_of<typename decay<F>::type()>::type R; +        if (int(policy) & int(launch::async)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          boost::thread( boost::move(pt) ).detach(); +          return ::boost::move(ret); +        } +        else if (int(policy) & int(launch::deferred)) +        { +          packaged_task<R> pt( boost::forward<F>(f) ); + +          BOOST_THREAD_FUTURE<R> ret = pt.get_future(); +          return ::boost::move(ret); +        } else { +          BOOST_THREAD_FUTURE<R> ret; +          return ::boost::move(ret); +        } +    } +    template <class F> +    BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type> +    async(BOOST_THREAD_FWD_REF(F) f) +    { +        return async(launch::any, boost::forward<F>(f)); +    }  #endif + +} + +#endif // BOOST_NO_EXCEPTION +#endif // header diff --git a/3rdParty/Boost/src/boost/thread/locks.hpp b/3rdParty/Boost/src/boost/thread/locks.hpp index d23e619..c11c2bd 100644 --- a/3rdParty/Boost/src/boost/thread/locks.hpp +++ b/3rdParty/Boost/src/boost/thread/locks.hpp @@ -2,6 +2,8 @@  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  // (C) Copyright 2007 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba +  #ifndef BOOST_THREAD_LOCKS_HPP  #define BOOST_THREAD_LOCKS_HPP  #include <boost/thread/detail/config.hpp> @@ -12,6 +14,10 @@  #include <boost/thread/thread_time.hpp>  #include <boost/detail/workaround.hpp>  #include <boost/type_traits/is_class.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/time_point.hpp> +#include <boost/chrono/duration.hpp> +#endif  #include <boost/config/abi_prefix.hpp> @@ -71,7 +77,7 @@ namespace boost          {              BOOST_STATIC_CONSTANT(bool, value=false);          }; -         +          template<typename T>          struct has_member_lock<T,true>          { @@ -80,22 +86,22 @@ namespace boost              {                  true_type dummy[2];              }; -             +              template<typename U,typename V>              static true_type has_member(V (U::*)());              template<typename U>              static false_type has_member(U); -             +              BOOST_STATIC_CONSTANT(                  bool,value=sizeof(has_member_lock<T>::has_member(&T::lock))==sizeof(true_type));          }; -         +          template<typename T,bool=has_member_called_unlock<T>::value >          struct has_member_unlock          {              BOOST_STATIC_CONSTANT(bool, value=false);          }; -         +          template<typename T>          struct has_member_unlock<T,true>          { @@ -104,22 +110,22 @@ namespace boost              {                  true_type dummy[2];              }; -             +              template<typename U,typename V>              static true_type has_member(V (U::*)());              template<typename U>              static false_type has_member(U); -             +              BOOST_STATIC_CONSTANT(                  bool,value=sizeof(has_member_unlock<T>::has_member(&T::unlock))==sizeof(true_type));          }; -         +          template<typename T,bool=has_member_called_try_lock<T>::value >          struct has_member_try_lock          {              BOOST_STATIC_CONSTANT(bool, value=false);          }; -         +          template<typename T>          struct has_member_try_lock<T,true>          { @@ -128,18 +134,18 @@ namespace boost              {                  true_type dummy[2];              }; -             +              template<typename U>              static true_type has_member(bool (U::*)());              template<typename U>              static false_type has_member(U); -             +              BOOST_STATIC_CONSTANT(                  bool,value=sizeof(has_member_try_lock<T>::has_member(&T::try_lock))==sizeof(true_type));          };      } -     +      template<typename T>      struct is_mutex_type @@ -147,7 +153,7 @@ namespace boost          BOOST_STATIC_CONSTANT(bool, value = detail::has_member_lock<T>::value &&                                detail::has_member_unlock<T>::value &&                                detail::has_member_try_lock<T>::value); -         +      };  #else      template<typename T> @@ -155,7 +161,7 @@ namespace boost      {          BOOST_STATIC_CONSTANT(bool, value = false);      }; -#endif     +#endif      struct defer_lock_t      {}; @@ -163,10 +169,10 @@ namespace boost      {};      struct adopt_lock_t      {}; -     -    const defer_lock_t defer_lock={}; -    const try_to_lock_t try_to_lock={}; -    const adopt_lock_t adopt_lock={}; + +    BOOST_CONSTEXPR_OR_CONST defer_lock_t defer_lock={}; +    BOOST_CONSTEXPR_OR_CONST try_to_lock_t try_to_lock={}; +    BOOST_CONSTEXPR_OR_CONST adopt_lock_t adopt_lock={};      template<typename Mutex>      class shared_lock; @@ -182,7 +188,7 @@ namespace boost          template<typename Mutex>          class try_lock_wrapper;      } -     +  #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES      template<typename T>      struct is_mutex_type<unique_lock<T> > @@ -201,7 +207,7 @@ namespace boost      {          BOOST_STATIC_CONSTANT(bool, value = true);      }; -     +      template<typename T>      struct is_mutex_type<detail::try_lock_wrapper<T> >      { @@ -213,7 +219,7 @@ namespace boost      class recursive_mutex;      class recursive_timed_mutex;      class shared_mutex; -     +      template<>      struct is_mutex_type<mutex>      { @@ -248,9 +254,10 @@ namespace boost      private:          Mutex& m; -        explicit lock_guard(lock_guard&); -        lock_guard& operator=(lock_guard&);      public: +        typedef Mutex mutex_type; +        BOOST_THREAD_NO_COPYABLE(lock_guard) +          explicit lock_guard(Mutex& m_):              m(m_)          { @@ -265,25 +272,29 @@ namespace boost          }      }; -      template<typename Mutex>      class unique_lock      {      private:          Mutex* m;          bool is_locked; -        unique_lock(unique_lock&); + +    private:          explicit unique_lock(upgrade_lock<Mutex>&); -        unique_lock& operator=(unique_lock&);          unique_lock& operator=(upgrade_lock<Mutex>& other);      public: -#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)  -        unique_lock(const volatile unique_lock&);  +        typedef Mutex mutex_type; +        BOOST_THREAD_MOVABLE_ONLY(unique_lock) + +#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) +        unique_lock(const volatile unique_lock&);  #endif -        unique_lock(): +#endif +        unique_lock() BOOST_NOEXCEPT :              m(0),is_locked(false)          {} -         +          explicit unique_lock(Mutex& m_):              m(&m_),is_locked(false)          { @@ -292,7 +303,7 @@ namespace boost          unique_lock(Mutex& m_,adopt_lock_t):              m(&m_),is_locked(true)          {} -        unique_lock(Mutex& m_,defer_lock_t): +        unique_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:              m(&m_),is_locked(false)          {}          unique_lock(Mutex& m_,try_to_lock_t): @@ -311,91 +322,172 @@ namespace boost          {              timed_lock(target_time);          } -#ifndef BOOST_NO_RVALUE_REFERENCES -        unique_lock(unique_lock&& other): -            m(other.m),is_locked(other.is_locked) + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +        unique_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) +                : m(&mtx), is_locked(mtx.try_lock_until(t))          { -            other.is_locked=false; -            other.m=0;          } -        explicit unique_lock(upgrade_lock<Mutex>&& other); - -        unique_lock<Mutex>&& move() +        template <class Rep, class Period> +        unique_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) +                : m(&mtx), is_locked(mtx.try_lock_for(d))          { -            return static_cast<unique_lock<Mutex>&&>(*this);          } +#endif +        unique_lock(BOOST_THREAD_RV_REF(unique_lock) other) BOOST_NOEXCEPT: +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked) +        { +          BOOST_THREAD_RV(other).is_locked=false; +          BOOST_THREAD_RV(other).m=0; +        } +        BOOST_THREAD_EXPLICIT_LOCK_CONVERSION unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other); -        unique_lock& operator=(unique_lock&& other) +#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +        unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)  BOOST_NOEXCEPT          { -            unique_lock temp(other.move()); +            unique_lock temp(::boost::move(other));              swap(temp);              return *this;          } +#endif -        unique_lock& operator=(upgrade_lock<Mutex>&& other) +        unique_lock& operator=(BOOST_THREAD_RV_REF(unique_lock) other)  BOOST_NOEXCEPT          { -            unique_lock temp(other.move()); +            unique_lock temp(::boost::move(other));              swap(temp);              return *this;          } -        void swap(unique_lock&& other) -        { -            std::swap(m,other.m); -            std::swap(is_locked,other.is_locked); -        } -#else -        unique_lock(detail::thread_move_t<unique_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) +#if 0 // This should not be needed anymore. Use instead BOOST_THREAD_MAKE_RV_REF. +#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100) +        unique_lock& operator=(unique_lock<Mutex> other)          { -            other->is_locked=false; -            other->m=0; +            swap(other); +            return *this;          } -        unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other); +#endif // BOOST_WORKAROUND +#endif -        operator detail::thread_move_t<unique_lock<Mutex> >() +        // Conversion from upgrade locking +        unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, try_to_lock_t) +        : m(0),is_locked(false)          { -            return move(); +            if (BOOST_THREAD_RV(ul).owns_lock()) { +              if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock()) +              { +                  m = BOOST_THREAD_RV(ul).release(); +                  is_locked = true; +              } +            } +            else +            { +              m = BOOST_THREAD_RV(ul).release(); +            }          } -        detail::thread_move_t<unique_lock<Mutex> > move() +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +        unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, +                    const chrono::time_point<Clock, Duration>& abs_time) +        : m(0),is_locked(false)          { -            return detail::thread_move_t<unique_lock<Mutex> >(*this); +            if (BOOST_THREAD_RV(ul).owns_lock()) { +              if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_until(abs_time)) +              { +                  m = BOOST_THREAD_RV(ul).release(); +                  is_locked = true; +              } +            } +            else +            { +              m = BOOST_THREAD_RV(ul).release(); +            }          } -#if BOOST_WORKAROUND(__SUNPRO_CC, < 0x5100)  -        unique_lock& operator=(unique_lock<Mutex> other)  -        {  -            swap(other);  -            return *this;  -        }  -#else -        unique_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) +        template <class Rep, class Period> +        unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<mutex_type> BOOST_THREAD_RV_REF_END ul, +                    const chrono::duration<Rep, Period>& rel_time) +        : m(0),is_locked(false)          { -            unique_lock temp(other); -            swap(temp); -            return *this; +          if (BOOST_THREAD_RV(ul).owns_lock()) { +            if (BOOST_THREAD_RV(ul).mutex()->try_unlock_upgrade_and_lock_for(rel_time)) +            { +              m = BOOST_THREAD_RV(ul).release(); +              is_locked = true; +            } +          } +          else +          { +            m = BOOST_THREAD_RV(ul).release(); +          }          }  #endif -        unique_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        // Conversion from shared locking +        unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) +        : m(0),is_locked(false)          { -            unique_lock temp(other); -            swap(temp); -            return *this; +          if (BOOST_THREAD_RV(sl).owns_lock()) { +            if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock()) +            { +                m = BOOST_THREAD_RV(sl).release(); +                is_locked = true; +            } +          } +          else +          { +            m = BOOST_THREAD_RV(sl).release(); +          } +        } + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +        unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, +                    const chrono::time_point<Clock, Duration>& abs_time) +        : m(0),is_locked(false) +        { +            if (BOOST_THREAD_RV(sl).owns_lock()) { +              if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_until(abs_time)) +              { +                  m = BOOST_THREAD_RV(sl).release(); +                  is_locked = true; +              } +            } +            else +            { +              m = BOOST_THREAD_RV(sl).release(); +            }          } -        void swap(detail::thread_move_t<unique_lock<Mutex> > other) + +        template <class Rep, class Period> +        unique_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, +                    const chrono::duration<Rep, Period>& rel_time) +        : m(0),is_locked(false)          { -            std::swap(m,other->m); -            std::swap(is_locked,other->is_locked); +              if (BOOST_THREAD_RV(sl).owns_lock()) { +                if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_for(rel_time)) +                { +                    m = BOOST_THREAD_RV(sl).release(); +                    is_locked = true; +                } +              } +              else +              { +                m = BOOST_THREAD_RV(sl).release(); +              }          } -#endif -        void swap(unique_lock& other) +#endif // BOOST_THREAD_USES_CHRONO +#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS + + +        void swap(unique_lock& other) BOOST_NOEXCEPT          {              std::swap(m,other.m);              std::swap(is_locked,other.is_locked);          } -         +          ~unique_lock()          {              if(owns_lock()) @@ -405,18 +497,26 @@ namespace boost          }          void lock()          { +            if(m==0) +            { +                boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +                boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));              }              m->lock();              is_locked=true;          }          bool try_lock()          { +            if(m==0) +            { +                boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +                boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex"));              }              is_locked=m->try_lock();              return is_locked; @@ -424,50 +524,118 @@ namespace boost          template<typename TimeDuration>          bool timed_lock(TimeDuration const& relative_time)          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex")); +          }              is_locked=m->timed_lock(relative_time);              return is_locked;          } -         +          bool timed_lock(::boost::system_time const& absolute_time)          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex")); +          }              is_locked=m->timed_lock(absolute_time);              return is_locked;          }          bool timed_lock(::boost::xtime const& absolute_time)          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex")); +          }              is_locked=m->timed_lock(absolute_time);              return is_locked;          } + +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex")); +          } +          is_locked=m->try_lock_for(rel_time); +          return is_locked; +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost unique_lock owns already the mutex")); +          } +          is_locked=m->try_lock_until(abs_time); +          return is_locked; +        } +#endif +          void unlock()          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock has no mutex")); +          }              if(!owns_lock())              { -                boost::throw_exception(boost::lock_error()); +                boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost unique_lock doesn't own the mutex"));              }              m->unlock();              is_locked=false;          } -             + +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)          typedef void (unique_lock::*bool_type)(); -        operator bool_type() const +        operator bool_type() const BOOST_NOEXCEPT          {              return is_locked?&unique_lock::lock:0;          } -        bool operator!() const +        bool operator!() const BOOST_NOEXCEPT          {              return !owns_lock();          } -        bool owns_lock() const +#else +        explicit operator bool() const BOOST_NOEXCEPT +        { +            return owns_lock(); +        } +#endif +        bool owns_lock() const BOOST_NOEXCEPT          {              return is_locked;          } -        Mutex* mutex() const +        Mutex* mutex() const BOOST_NOEXCEPT          {              return m;          } -        Mutex* release() +        Mutex* release() BOOST_NOEXCEPT          {              Mutex* const res=m;              m=0; @@ -479,44 +647,13 @@ namespace boost          friend class upgrade_lock<Mutex>;      }; -#ifndef BOOST_NO_RVALUE_REFERENCES -    template<typename Mutex> -    void swap(unique_lock<Mutex>&& lhs,unique_lock<Mutex>&& rhs) -    { -        lhs.swap(rhs); -    } - -    template<typename Mutex> -    inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>&& ul) -    { -        return static_cast<upgrade_lock<Mutex>&&>(ul); -    } - -    template<typename Mutex> -    inline upgrade_lock<Mutex>&& move(upgrade_lock<Mutex>& ul) -    { -        return static_cast<upgrade_lock<Mutex>&&>(ul); -    } -#endif      template<typename Mutex> -    void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs) +    void swap(unique_lock<Mutex>& lhs,unique_lock<Mutex>& rhs) BOOST_NOEXCEPT      {          lhs.swap(rhs);      } -#ifndef BOOST_NO_RVALUE_REFERENCES -    template<typename Mutex> -    inline unique_lock<Mutex>&& move(unique_lock<Mutex>&& ul) -    { -        return static_cast<unique_lock<Mutex>&&>(ul); -    } - -    template<typename Mutex> -    inline unique_lock<Mutex>&& move(unique_lock<Mutex>& ul) -    { -        return static_cast<unique_lock<Mutex>&&>(ul); -    } -#endif +    BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END      template<typename Mutex>      class shared_lock @@ -524,14 +661,15 @@ namespace boost      protected:          Mutex* m;          bool is_locked; -    private: -        explicit shared_lock(shared_lock&); -        shared_lock& operator=(shared_lock&); +      public: -        shared_lock(): +        typedef Mutex mutex_type; +        BOOST_THREAD_MOVABLE_ONLY(shared_lock) + +        shared_lock() BOOST_NOEXCEPT:              m(0),is_locked(false)          {} -         +          explicit shared_lock(Mutex& m_):              m(&m_),is_locked(false)          { @@ -540,7 +678,7 @@ namespace boost          shared_lock(Mutex& m_,adopt_lock_t):              m(&m_),is_locked(true)          {} -        shared_lock(Mutex& m_,defer_lock_t): +        shared_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:              m(&m_),is_locked(false)          {}          shared_lock(Mutex& m_,try_to_lock_t): @@ -554,91 +692,90 @@ namespace boost              timed_lock(target_time);          } -        shared_lock(detail::thread_move_t<shared_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +        shared_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) +                : m(&mtx), is_locked(mtx.try_lock_shared_until(t)) +        { +        } +        template <class Rep, class Period> +        shared_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) +                : m(&mtx), is_locked(mtx.try_lock_shared_for(d)) +        { +        } +#endif + +        shared_lock(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)          { -            other->is_locked=false; -            other->m=0; +            BOOST_THREAD_RV(other).is_locked=false; +            BOOST_THREAD_RV(other).m=0;          } -        shared_lock(detail::thread_move_t<unique_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) +        BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)          {              if(is_locked)              {                  m->unlock_and_lock_shared();              } -            other->is_locked=false; -            other->m=0; +            BOOST_THREAD_RV(other).is_locked=false; +            BOOST_THREAD_RV(other).m=0;          } -        shared_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) +        BOOST_THREAD_EXPLICIT_LOCK_CONVERSION shared_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)          {              if(is_locked)              {                  m->unlock_upgrade_and_lock_shared();              } -            other->is_locked=false; -            other->m=0; +            BOOST_THREAD_RV(other).is_locked=false; +            BOOST_THREAD_RV(other).m=0;          } -        operator detail::thread_move_t<shared_lock<Mutex> >() -        { -            return move(); -        } -        detail::thread_move_t<shared_lock<Mutex> > move() +        shared_lock& operator=(BOOST_THREAD_RV_REF_BEG shared_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT          { -            return detail::thread_move_t<shared_lock<Mutex> >(*this); -        } - - -        shared_lock& operator=(detail::thread_move_t<shared_lock<Mutex> > other) -        { -            shared_lock temp(other); +            shared_lock temp(::boost::move(other));              swap(temp);              return *this;          } - -        shared_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) +#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +        shared_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)          { -            shared_lock temp(other); +            shared_lock temp(::boost::move(other));              swap(temp);              return *this;          } -        shared_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) +        shared_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other)          { -            shared_lock temp(other); +            shared_lock temp(::boost::move(other));              swap(temp);              return *this;          } +#endif -#ifndef BOOST_NO_RVALUE_REFERENCES -        void swap(shared_lock&& other) +        void swap(shared_lock& other) BOOST_NOEXCEPT          {              std::swap(m,other.m);              std::swap(is_locked,other.is_locked);          } -#else -        void swap(boost::detail::thread_move_t<shared_lock<Mutex> > other) -        { -            std::swap(m,other->m); -            std::swap(is_locked,other->is_locked); -        } -#endif -        void swap(shared_lock& other) + +        Mutex* mutex() const BOOST_NOEXCEPT          { -            std::swap(m,other.m); -            std::swap(is_locked,other.is_locked); +            return m;          } -        Mutex* mutex() const +        Mutex* release() BOOST_NOEXCEPT          { -            return m; +            Mutex* const res=m; +            m=0; +            is_locked=false; +            return res;          } -         +          ~shared_lock()          {              if(owns_lock()) @@ -648,27 +785,39 @@ namespace boost          }          void lock()          { +            if(m==0) +            { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));              }              m->lock_shared();              is_locked=true;          }          bool try_lock()          { +            if(m==0) +            { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));              }              is_locked=m->try_lock_shared();              return is_locked;          }          bool timed_lock(boost::system_time const& target_time)          { +            if(m==0) +            { +                boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));              }              is_locked=m->timed_lock_shared(target_time);              return is_locked; @@ -676,52 +825,91 @@ namespace boost          template<typename Duration>          bool timed_lock(Duration const& target_time)          { +            if(m==0) +            { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +            }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex"));              }              is_locked=m->timed_lock_shared(target_time);              return is_locked;          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex")); +          } +          is_locked=m->try_lock_shared_for(rel_time); +          return is_locked; +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex")); +          } +          is_locked=m->try_lock_shared_until(abs_time); +          return is_locked; +        } +#endif          void unlock()          { +            if(m==0) +            { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +            }              if(!owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock doesn't own the mutex"));              }              m->unlock_shared();              is_locked=false;          } -             + +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)          typedef void (shared_lock<Mutex>::*bool_type)(); -        operator bool_type() const +        operator bool_type() const BOOST_NOEXCEPT          {              return is_locked?&shared_lock::lock:0;          } -        bool operator!() const +        bool operator!() const BOOST_NOEXCEPT          {              return !owns_lock();          } -        bool owns_lock() const +#else +        explicit operator bool() const BOOST_NOEXCEPT +        { +            return owns_lock(); +        } +#endif +        bool owns_lock() const BOOST_NOEXCEPT          {              return is_locked;          }      }; -#ifndef BOOST_NO_RVALUE_REFERENCES -    template<typename Mutex> -    void swap(shared_lock<Mutex>&& lhs,shared_lock<Mutex>&& rhs) -    { -        lhs.swap(rhs); -    } -#else +    BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) shared_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END +      template<typename Mutex> -    void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) +    void swap(shared_lock<Mutex>& lhs,shared_lock<Mutex>& rhs) BOOST_NOEXCEPT      {          lhs.swap(rhs);      } -#endif      template<typename Mutex>      class upgrade_lock @@ -729,14 +917,15 @@ namespace boost      protected:          Mutex* m;          bool is_locked; -    private: -        explicit upgrade_lock(upgrade_lock&); -        upgrade_lock& operator=(upgrade_lock&); +      public: -        upgrade_lock(): +        typedef Mutex mutex_type; +        BOOST_THREAD_MOVABLE_ONLY(upgrade_lock) + +        upgrade_lock() BOOST_NOEXCEPT:              m(0),is_locked(false)          {} -         +          explicit upgrade_lock(Mutex& m_):              m(&m_),is_locked(false)          { @@ -745,7 +934,7 @@ namespace boost          upgrade_lock(Mutex& m_,adopt_lock_t):              m(&m_),is_locked(true)          {} -        upgrade_lock(Mutex& m_,defer_lock_t): +        upgrade_lock(Mutex& m_,defer_lock_t) BOOST_NOEXCEPT:              m(&m_),is_locked(false)          {}          upgrade_lock(Mutex& m_,try_to_lock_t): @@ -753,89 +942,128 @@ namespace boost          {              try_lock();          } -#ifdef BOOST_HAS_RVALUE_REFS -        upgrade_lock(upgrade_lock<Mutex>&& other): -            m(other.m),is_locked(other.is_locked) + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +        upgrade_lock(Mutex& mtx, const chrono::time_point<Clock, Duration>& t) +                : m(&mtx), is_locked(mtx.try_lock_upgrade_until(t)) +        { +        } +        template <class Rep, class Period> +        upgrade_lock(Mutex& mtx, const chrono::duration<Rep, Period>& d) +                : m(&mtx), is_locked(mtx.try_lock_upgrade_for(d)) +        { +        } +#endif + +        upgrade_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)          { -            other.is_locked=false; -            other.m=0; +            BOOST_THREAD_RV(other).is_locked=false; +            BOOST_THREAD_RV(other).m=0;          } -        upgrade_lock(unique_lock<Mutex>&& other): -            m(other.m),is_locked(other.is_locked) +        BOOST_THREAD_EXPLICIT_LOCK_CONVERSION upgrade_lock(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other): +            m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)          {              if(is_locked)              {                  m->unlock_and_lock_upgrade();              } -            other.is_locked=false; -            other.m=0; +            BOOST_THREAD_RV(other).is_locked=false; +            BOOST_THREAD_RV(other).m=0;          } -        upgrade_lock& operator=(upgrade_lock<Mutex>&& other) +        upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT          { -            upgrade_lock temp(static_cast<upgrade_lock<Mutex>&&>(other)); +            upgrade_lock temp(::boost::move(other));              swap(temp);              return *this;          } -        upgrade_lock& operator=(unique_lock<Mutex>&& other) +#ifndef BOOST_THREAD_PROVIDES_EXPLICIT_LOCK_CONVERSION +        upgrade_lock& operator=(BOOST_THREAD_RV_REF_BEG unique_lock<Mutex> BOOST_THREAD_RV_REF_END other)          { -            upgrade_lock temp(static_cast<unique_lock<Mutex>&&>(other)); +            upgrade_lock temp(::boost::move(other));              swap(temp);              return *this;          } -#else -        upgrade_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) -        { -            other->is_locked=false; -            other->m=0; -        } +#endif -        upgrade_lock(detail::thread_move_t<unique_lock<Mutex> > other): -            m(other->m),is_locked(other->is_locked) +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        // Conversion from shared locking +        upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, try_to_lock_t) +        : m(0),is_locked(false)          { -            if(is_locked) +          if (BOOST_THREAD_RV(sl).owns_lock()) { +            if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade())              { -                m->unlock_and_lock_upgrade(); +                m = BOOST_THREAD_RV(sl).release(); +                is_locked = true;              } -            other->is_locked=false; -            other->m=0; +          } +          else +          { +            m = BOOST_THREAD_RV(sl).release(); +          }          } -        operator detail::thread_move_t<upgrade_lock<Mutex> >() +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Clock, class Duration> +            upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, +                         const chrono::time_point<Clock, Duration>& abs_time) +        : m(0),is_locked(false)          { -            return move(); +          if (BOOST_THREAD_RV(sl).owns_lock()) { +            if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_until(abs_time)) +            { +                m = BOOST_THREAD_RV(sl).release(); +                is_locked = true; +            } +          } +          else +          { +            m = BOOST_THREAD_RV(sl).release(); +          }          } -        detail::thread_move_t<upgrade_lock<Mutex> > move() +        template <class Rep, class Period> +            upgrade_lock(BOOST_THREAD_RV_REF_BEG shared_lock<mutex_type> BOOST_THREAD_RV_REF_END sl, +                         const chrono::duration<Rep, Period>& rel_time) +        : m(0),is_locked(false)          { -            return detail::thread_move_t<upgrade_lock<Mutex> >(*this); +          if (BOOST_THREAD_RV(sl).owns_lock()) { +            if (BOOST_THREAD_RV(sl).mutex()->try_unlock_shared_and_lock_upgrade_for(rel_time)) +            { +                m = BOOST_THREAD_RV(sl).release(); +                is_locked = true; +            } +          } +          else +          { +            m = BOOST_THREAD_RV(sl).release(); +          }          } +#endif // BOOST_THREAD_USES_CHRONO +#endif // BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS - -        upgrade_lock& operator=(detail::thread_move_t<upgrade_lock<Mutex> > other) +        void swap(upgrade_lock& other) BOOST_NOEXCEPT          { -            upgrade_lock temp(other); -            swap(temp); -            return *this; +            std::swap(m,other.m); +            std::swap(is_locked,other.is_locked);          } - -        upgrade_lock& operator=(detail::thread_move_t<unique_lock<Mutex> > other) +        Mutex* mutex() const BOOST_NOEXCEPT          { -            upgrade_lock temp(other); -            swap(temp); -            return *this; +            return m;          } -#endif -        void swap(upgrade_lock& other) +        Mutex* release() BOOST_NOEXCEPT          { -            std::swap(m,other.m); -            std::swap(is_locked,other.is_locked); +            Mutex* const res=m; +            m=0; +            is_locked=false; +            return res;          } -                  ~upgrade_lock()          {              if(owns_lock()) @@ -845,42 +1073,90 @@ namespace boost          }          void lock()          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));              }              m->lock_upgrade();              is_locked=true;          }          bool try_lock()          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          }              if(owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost upgrade_lock owns already the mutex"));              }              is_locked=m->try_lock_upgrade();              return is_locked;          }          void unlock()          { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          }              if(!owns_lock())              { -                boost::throw_exception(boost::lock_error()); +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost upgrade_lock doesn't own the mutex"));              }              m->unlock_upgrade();              is_locked=false;          } -             +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex")); +          } +          is_locked=m->try_lock_upgrade_for(rel_time); +          return is_locked; +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          if(m==0) +          { +              boost::throw_exception(boost::lock_error(system::errc::operation_not_permitted, "boost shared_lock has no mutex")); +          } +          if(owns_lock()) +          { +              boost::throw_exception(boost::lock_error(system::errc::resource_deadlock_would_occur, "boost shared_lock owns already the mutex")); +          } +          is_locked=m->try_lock_upgrade_until(abs_time); +          return is_locked; +        } +#endif +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)          typedef void (upgrade_lock::*bool_type)(); -        operator bool_type() const +        operator bool_type() const BOOST_NOEXCEPT          {              return is_locked?&upgrade_lock::lock:0;          } -        bool operator!() const +        bool operator!() const BOOST_NOEXCEPT          {              return !owns_lock();          } -        bool owns_lock() const +#else +        explicit operator bool() const BOOST_NOEXCEPT +        { +            return owns_lock(); +        } +#endif +        bool owns_lock() const BOOST_NOEXCEPT          {              return is_locked;          } @@ -888,30 +1164,25 @@ namespace boost          friend class unique_lock<Mutex>;      }; - -#ifndef BOOST_NO_RVALUE_REFERENCES      template<typename Mutex> -    unique_lock<Mutex>::unique_lock(upgrade_lock<Mutex>&& other): -        m(other.m),is_locked(other.is_locked) +    void swap(upgrade_lock<Mutex>& lhs,upgrade_lock<Mutex>& rhs) BOOST_NOEXCEPT      { -        other.is_locked=false; -        if(is_locked) -        { -            m->unlock_upgrade_and_lock(); -        } +        lhs.swap(rhs);      } -#else + +    BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END +      template<typename Mutex> -    unique_lock<Mutex>::unique_lock(detail::thread_move_t<upgrade_lock<Mutex> > other): -        m(other->m),is_locked(other->is_locked) +    unique_lock<Mutex>::unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_lock<Mutex> BOOST_THREAD_RV_REF_END other): +        m(BOOST_THREAD_RV(other).m),is_locked(BOOST_THREAD_RV(other).is_locked)      { -        other->is_locked=false;          if(is_locked)          {              m->unlock_upgrade_and_lock();          } +        BOOST_THREAD_RV(other).release();      } -#endif +      template <class Mutex>      class upgrade_to_unique_lock      { @@ -919,67 +1190,65 @@ namespace boost          upgrade_lock<Mutex>* source;          unique_lock<Mutex> exclusive; -        explicit upgrade_to_unique_lock(upgrade_to_unique_lock&); -        upgrade_to_unique_lock& operator=(upgrade_to_unique_lock&);      public: +        typedef Mutex mutex_type; +        BOOST_THREAD_MOVABLE_ONLY(upgrade_to_unique_lock) +          explicit upgrade_to_unique_lock(upgrade_lock<Mutex>& m_): -            source(&m_),exclusive(move(*source)) +            source(&m_),exclusive(::boost::move(*source))          {}          ~upgrade_to_unique_lock()          {              if(source)              { -                *source=move(exclusive); +                *source=BOOST_THREAD_MAKE_RV_REF(upgrade_lock<Mutex>(::boost::move(exclusive)));              }          } -#ifdef BOOST_HAS_RVALUE_REFS -        upgrade_to_unique_lock(upgrade_to_unique_lock<Mutex>&& other): -            source(other.source),exclusive(move(other.exclusive)) -        { -            other.source=0; -        } -         -        upgrade_to_unique_lock& operator=(upgrade_to_unique_lock<Mutex>&& other) -        { -            upgrade_to_unique_lock temp(other); -            swap(temp); -            return *this; -        } -#else -        upgrade_to_unique_lock(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other): -            source(other->source),exclusive(move(other->exclusive)) +        upgrade_to_unique_lock(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT: +            source(BOOST_THREAD_RV(other).source),exclusive(::boost::move(BOOST_THREAD_RV(other).exclusive))          { -            other->source=0; +            BOOST_THREAD_RV(other).source=0;          } -         -        upgrade_to_unique_lock& operator=(detail::thread_move_t<upgrade_to_unique_lock<Mutex> > other) + +        upgrade_to_unique_lock& operator=(BOOST_THREAD_RV_REF_BEG upgrade_to_unique_lock<Mutex> BOOST_THREAD_RV_REF_END other) BOOST_NOEXCEPT          {              upgrade_to_unique_lock temp(other);              swap(temp);              return *this;          } -#endif -        void swap(upgrade_to_unique_lock& other) + +        void swap(upgrade_to_unique_lock& other) BOOST_NOEXCEPT          {              std::swap(source,other.source);              exclusive.swap(other.exclusive);          } + +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)          typedef void (upgrade_to_unique_lock::*bool_type)(upgrade_to_unique_lock&); -        operator bool_type() const +        operator bool_type() const BOOST_NOEXCEPT          {              return exclusive.owns_lock()?&upgrade_to_unique_lock::swap:0;          } -        bool operator!() const +        bool operator!() const BOOST_NOEXCEPT          {              return !owns_lock();          } -        bool owns_lock() const +#else +        explicit operator bool() const BOOST_NOEXCEPT +        { +            return owns_lock(); +        } +#endif + +        bool owns_lock() const BOOST_NOEXCEPT          {              return exclusive.owns_lock();          }      }; +    BOOST_THREAD_DCL_MOVABLE_BEG(Mutex) upgrade_to_unique_lock<Mutex> BOOST_THREAD_DCL_MOVABLE_END +      namespace detail      {          template<typename Mutex> @@ -988,9 +1257,11 @@ namespace boost          {              typedef unique_lock<Mutex> base;          public: +            BOOST_THREAD_MOVABLE_ONLY(try_lock_wrapper) +              try_lock_wrapper()              {} -             +              explicit try_lock_wrapper(Mutex& m):                  base(m,try_to_lock)              {} @@ -1004,54 +1275,27 @@ namespace boost              try_lock_wrapper(Mutex& m_,try_to_lock_t):                  base(m_,try_to_lock)              {} -#ifndef BOOST_NO_RVALUE_REFERENCES -            try_lock_wrapper(try_lock_wrapper&& other): -                base(other.move()) +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +            try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): +                base(::boost::move(other))              {} -            try_lock_wrapper&& move() -            { -                return static_cast<try_lock_wrapper&&>(*this); -            } - -            try_lock_wrapper& operator=(try_lock_wrapper<Mutex>&& other) -            { -                try_lock_wrapper temp(other.move()); -                swap(temp); -                return *this; -            } +#elif defined BOOST_THREAD_USES_MOVE +            try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): +                base(::boost::move(static_cast<base&>(other))) +            {} -            void swap(try_lock_wrapper&& other) -            { -                base::swap(other); -            }  #else -            try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other): -                base(detail::thread_move_t<base>(*other)) +            try_lock_wrapper(BOOST_THREAD_RV_REF(try_lock_wrapper) other): +                base(BOOST_THREAD_RV_REF(base)(*other))              {} - -            operator detail::thread_move_t<try_lock_wrapper<Mutex> >() -            { -                return move(); -            } - -            detail::thread_move_t<try_lock_wrapper<Mutex> > move() -            { -                return detail::thread_move_t<try_lock_wrapper<Mutex> >(*this); -            } - -            try_lock_wrapper& operator=(detail::thread_move_t<try_lock_wrapper<Mutex> > other) +#endif +            try_lock_wrapper& operator=(BOOST_THREAD_RV_REF_BEG try_lock_wrapper<Mutex> BOOST_THREAD_RV_REF_END other)              {                  try_lock_wrapper temp(other);                  swap(temp);                  return *this;              } - -            void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other) -            { -                base::swap(*other); -            } -#endif              void swap(try_lock_wrapper& other)              {                  base::swap(other); @@ -1080,32 +1324,31 @@ namespace boost              {                  return base::release();              } -            bool operator!() const -            { -                return !this->owns_lock(); -            } +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)              typedef typename base::bool_type bool_type;              operator bool_type() const              {                  return base::operator bool_type();              } +            bool operator!() const +            { +                return !this->owns_lock(); +            } +#else +            explicit operator bool() const +            { +                return owns_lock(); +            } +#endif          }; -#ifndef BOOST_NO_RVALUE_REFERENCES -        template<typename Mutex> -        void swap(try_lock_wrapper<Mutex>&& lhs,try_lock_wrapper<Mutex>&& rhs) -        { -            lhs.swap(rhs); -        } -#else          template<typename Mutex>          void swap(try_lock_wrapper<Mutex>& lhs,try_lock_wrapper<Mutex>& rhs)          {              lhs.swap(rhs);          } -#endif -         +          template<typename MutexType1,typename MutexType2>          unsigned try_lock_internal(MutexType1& m1,MutexType2& m2)          { @@ -1234,7 +1477,7 @@ namespace boost          template<bool x>          struct is_mutex_type_wrapper          {}; -         +          template<typename MutexType1,typename MutexType2>          void lock_impl(MutexType1& m1,MutexType2& m2,is_mutex_type_wrapper<true>)          { @@ -1262,7 +1505,7 @@ namespace boost          template<typename Iterator>          void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);      } -     +      template<typename MutexType1,typename MutexType2>      void lock(MutexType1& m1,MutexType2& m2) @@ -1407,7 +1650,7 @@ namespace boost          {              typedef int type;          }; -         +          template<typename Iterator>          struct try_lock_impl_return<Iterator,false>          { @@ -1423,7 +1666,7 @@ namespace boost          template<typename Iterator>          Iterator try_lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>);      } -     +      template<typename MutexType1,typename MutexType2>      typename detail::try_lock_impl_return<MutexType1>::type try_lock(MutexType1& m1,MutexType2& m2)      { @@ -1465,7 +1708,7 @@ namespace boost      {          return ((int)detail::try_lock_internal(m1,m2,m3,m4,m5))-1;      } -     +      namespace detail      { @@ -1474,13 +1717,13 @@ namespace boost          {              Iterator begin;              Iterator end; -             +              range_lock_guard(Iterator begin_,Iterator end_):                  begin(begin_),end(end_)              { -                lock(begin,end); +                boost::lock(begin,end);              } -             +              void release()              {                  begin=end; @@ -1505,21 +1748,21 @@ namespace boost              }              typedef typename std::iterator_traits<Iterator>::value_type lock_type;              unique_lock<lock_type> guard(*begin,try_to_lock); -             +              if(!guard.owns_lock())              {                  return begin;              } -            Iterator const failed=try_lock(++begin,end); +            Iterator const failed=boost::try_lock(++begin,end);              if(failed==end)              {                  guard.release();              } -             +              return failed;          }      } -     +      namespace detail      { @@ -1527,7 +1770,7 @@ namespace boost          void lock_impl(Iterator begin,Iterator end,is_mutex_type_wrapper<false>)          {              typedef typename std::iterator_traits<Iterator>::value_type lock_type; -         +              if(begin==end)              {                  return; @@ -1536,14 +1779,14 @@ namespace boost              Iterator second=begin;              ++second;              Iterator next=second; -         +              for(;;)              {                  unique_lock<lock_type> begin_lock(*begin,defer_lock);                  if(start_with_begin)                  {                      begin_lock.lock(); -                    Iterator const failed_lock=try_lock(next,end); +                    Iterator const failed_lock=boost::try_lock(next,end);                      if(failed_lock==end)                      {                          begin_lock.release(); @@ -1557,7 +1800,7 @@ namespace boost                      detail::range_lock_guard<Iterator> guard(next,end);                      if(begin_lock.try_lock())                      { -                        Iterator const failed_lock=try_lock(second,next); +                        Iterator const failed_lock=boost::try_lock(second,next);                          if(failed_lock==next)                          {                              begin_lock.release(); @@ -1575,11 +1818,10 @@ namespace boost                  }              }          } -         +      } -     -} +}  #include <boost/config/abi_suffix.hpp>  #endif diff --git a/3rdParty/Boost/src/boost/thread/once.hpp b/3rdParty/Boost/src/boost/thread/once.hpp index 975304e..acd216e 100644 --- a/3rdParty/Boost/src/boost/thread/once.hpp +++ b/3rdParty/Boost/src/boost/thread/once.hpp @@ -3,7 +3,7 @@  //  once.hpp  // -//  (C) Copyright 2006-7 Anthony Williams  +//  (C) Copyright 2006-7 Anthony Williams  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at @@ -22,6 +22,8 @@  namespace boost  { +  // template<class Callable, class ...Args> void +  // call_once(once_flag& flag, Callable&& func, Args&&... args);      inline void call_once(void (*func)(),once_flag& flag)      {          call_once(flag,func); diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp index 9c5bee2..aa71007 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable.hpp @@ -4,11 +4,17 @@  // 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 2011 Vicente J. Botet Escriba -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" -#include "thread_data.hpp" -#include "condition_variable_fwd.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#include <boost/thread/pthread/thread_data.hpp> +#include <boost/thread/pthread/condition_variable_fwd.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #include <boost/config/abi_prefix.hpp> @@ -18,14 +24,14 @@ namespace boost      {          void BOOST_THREAD_DECL interruption_point();      } -     +      namespace thread_cv_detail      {          template<typename MutexType>          struct lock_on_exit          {              MutexType* m; -             +              lock_on_exit():                  m(0)              {} @@ -44,66 +50,82 @@ namespace boost             }          };      } -     +      inline void condition_variable::wait(unique_lock<mutex>& m)      { -        thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; -        detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -        guard.activate(m); -        int const res=pthread_cond_wait(&cond,&internal_mutex); -        BOOST_ASSERT(!res); +        int res=0; +        { +            thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; +            detail::interruption_checker check_for_interruption(&internal_mutex,&cond); +            guard.activate(m); +            do { +              res = pthread_cond_wait(&cond,&internal_mutex); +            } while (res == EINTR); +        }          this_thread::interruption_point(); +        if(res) +        { +            boost::throw_exception(condition_error(res, "boost:: condition_variable constructor failed in pthread_cond_wait")); +        }      } -    inline bool condition_variable::timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) +    inline bool condition_variable::do_timed_wait( +                unique_lock<mutex>& m, +                struct timespec const &timeout)      { +        if (!m.owns_lock()) +            boost::throw_exception(condition_error(EPERM, "condition_variable do_timed_wait: mutex not locked")); +          thread_cv_detail::lock_on_exit<unique_lock<mutex> > guard; -        detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -        guard.activate(m); -        struct timespec const timeout=detail::get_timespec(wait_until); -        int const cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +        int cond_res; +        { +            detail::interruption_checker check_for_interruption(&internal_mutex,&cond); +            guard.activate(m); +            cond_res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +        }          this_thread::interruption_point();          if(cond_res==ETIMEDOUT)          {              return false;          } -        BOOST_ASSERT(!cond_res); +        if(cond_res) +        { +            boost::throw_exception(condition_error(cond_res, "condition_variable failed in pthread_cond_timedwait")); +        }          return true;      } -    inline void condition_variable::notify_one() +    inline void condition_variable::notify_one() BOOST_NOEXCEPT      {          boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);          BOOST_VERIFY(!pthread_cond_signal(&cond));      } -         -    inline void condition_variable::notify_all() + +    inline void condition_variable::notify_all() BOOST_NOEXCEPT      {          boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);          BOOST_VERIFY(!pthread_cond_broadcast(&cond));      } -     +      class condition_variable_any      {          pthread_mutex_t internal_mutex;          pthread_cond_t cond; -        condition_variable_any(condition_variable_any&); -        condition_variable_any& operator=(condition_variable_any&); -      public: +        BOOST_THREAD_NO_COPYABLE(condition_variable_any)          condition_variable_any()          {              int const res=pthread_mutex_init(&internal_mutex,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "condition_variable_any failed in pthread_cond_init"));              }          }          ~condition_variable_any() @@ -111,7 +133,7 @@ namespace boost              BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex));              BOOST_VERIFY(!pthread_cond_destroy(&cond));          } -         +          template<typename lock_type>          void wait(lock_type& m)          { @@ -121,11 +143,11 @@ namespace boost                  detail::interruption_checker check_for_interruption(&internal_mutex,&cond);                  guard.activate(m);                  res=pthread_cond_wait(&cond,&internal_mutex); -                this_thread::interruption_point();              } +            this_thread::interruption_point();              if(res)              { -                boost::throw_exception(condition_error()); +                boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_wait"));              }          } @@ -134,28 +156,12 @@ namespace boost          {              while(!pred()) wait(m);          } -         +          template<typename lock_type>          bool timed_wait(lock_type& m,boost::system_time const& wait_until)          {              struct timespec const timeout=detail::get_timespec(wait_until); -            int res=0; -            { -                thread_cv_detail::lock_on_exit<lock_type> guard; -                detail::interruption_checker check_for_interruption(&internal_mutex,&cond); -                guard.activate(m); -                res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); -                this_thread::interruption_point(); -            } -            if(res==ETIMEDOUT) -            { -                return false; -            } -            if(res) -            { -                boost::throw_exception(condition_error()); -            } -            return true; +            return do_timed_wait(m, timeout);          }          template<typename lock_type>          bool timed_wait(lock_type& m,xtime const& wait_until) @@ -192,17 +198,134 @@ namespace boost              return timed_wait(m,get_system_time()+wait_duration,pred);          } -        void notify_one() +#ifdef BOOST_THREAD_USES_CHRONO +        template <class lock_type,class Duration> +        cv_status +        wait_until( +                lock_type& lock, +                const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          wait_until(lock, +                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +          return system_clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class lock_type, class Clock, class Duration> +        cv_status +        wait_until( +                lock_type& lock, +                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(); +          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now)); +          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; +        } + +        template <class lock_type, class Clock, class Duration, class Predicate> +        bool +        wait_until( +                lock_type& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } + + +        template <class lock_type, class Rep, class Period> +        cv_status +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          system_clock::time_point s_now = system_clock::now(); +          steady_clock::time_point c_now = steady_clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(d)); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; + +        } + + +        template <class lock_type, class Rep, class Period, class Predicate> +        bool +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +          while (!pred()) +          { +              if (wait_for(lock, d) == cv_status::timeout) +                  return pred(); +          } +          return true; +        } + +        template <class lock_type> +        inline void wait_until( +            lock_type& lk, +            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()); +            do_timed_wait(lk, ts); +        } +#endif + +        void notify_one() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         -        void notify_all() + +        void notify_all() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);              BOOST_VERIFY(!pthread_cond_broadcast(&cond));          } +    private: // used by boost::thread::try_join_until + +        template <class lock_type> +        inline bool do_timed_wait( +          lock_type& m, +          struct timespec const &timeout) +        { +          int res=0; +          { +              thread_cv_detail::lock_on_exit<lock_type> guard; +              detail::interruption_checker check_for_interruption(&internal_mutex,&cond); +              guard.activate(m); +              res=pthread_cond_timedwait(&cond,&internal_mutex,&timeout); +          } +          this_thread::interruption_point(); +          if(res==ETIMEDOUT) +          { +              return false; +          } +          if(res) +          { +              boost::throw_exception(condition_error(res, "condition_variable_any failed in pthread_cond_timedwait")); +          } +          return true; +        } + +      };  } diff --git a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp index 365f511..dbb3892 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/condition_variable_fwd.hpp @@ -4,47 +4,57 @@  // 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 Vicente J. Botet Escriba  #include <boost/assert.hpp>  #include <boost/throw_exception.hpp>  #include <pthread.h> +#include <boost/thread/cv_status.hpp>  #include <boost/thread/mutex.hpp>  #include <boost/thread/locks.hpp>  #include <boost/thread/thread_time.hpp>  #include <boost/thread/xtime.hpp> - +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp> +#include <boost/date_time/posix_time/posix_time_duration.hpp>  #include <boost/config/abi_prefix.hpp>  namespace boost  { +      class condition_variable      {      private:          pthread_mutex_t internal_mutex;          pthread_cond_t cond; -         -        condition_variable(condition_variable&); -        condition_variable& operator=(condition_variable&);      public: +      BOOST_THREAD_NO_COPYABLE(condition_variable)          condition_variable()          {              int const res=pthread_mutex_init(&internal_mutex,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: condition_variable constructor failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: condition_variable constructor failed in pthread_cond_init"));              }          }          ~condition_variable()          {              BOOST_VERIFY(!pthread_mutex_destroy(&internal_mutex)); -            BOOST_VERIFY(!pthread_cond_destroy(&cond)); +            int ret; +            do { +              ret = pthread_cond_destroy(&cond); +            } while (ret == EINTR); +            BOOST_VERIFY(!ret);          }          void wait(unique_lock<mutex>& m); @@ -55,21 +65,38 @@ namespace boost              while(!pred()) wait(m);          } -        inline bool timed_wait(unique_lock<mutex>& m, -                               boost::system_time const& wait_until); -        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until) + +        inline bool timed_wait( +            unique_lock<mutex>& m, +            boost::system_time const& wait_until) +        { +#if defined BOOST_THREAD_WAIT_BUG +            struct timespec const timeout=detail::get_timespec(wait_until + BOOST_THREAD_WAIT_BUG); +            return do_timed_wait(m, timeout); +#else +            struct timespec const timeout=detail::get_timespec(wait_until); +            return do_timed_wait(m, timeout); +#endif +        } +        bool timed_wait( +            unique_lock<mutex>& m, +            xtime const& wait_until)          {              return timed_wait(m,system_time(wait_until));          }          template<typename duration_type> -        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) +        bool timed_wait( +            unique_lock<mutex>& m, +            duration_type const& wait_duration)          {              return timed_wait(m,get_system_time()+wait_duration);          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            boost::system_time const& wait_until,predicate_type pred)          {              while (!pred())              { @@ -80,28 +107,133 @@ namespace boost          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,xtime const& wait_until,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            xtime const& wait_until,predicate_type pred)          {              return timed_wait(m,system_time(wait_until),pred);          }          template<typename duration_type,typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) +        bool timed_wait( +            unique_lock<mutex>& m, +            duration_type const& wait_duration,predicate_type pred)          {              return timed_wait(m,get_system_time()+wait_duration,pred);          } +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Duration> +        cv_status +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          wait_until(lock, +                        nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +          return system_clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class Clock, class Duration> +        cv_status +        wait_until( +                unique_lock<mutex>& lock, +                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(); +          wait_until(lock, s_now + ceil<nanoseconds>(t - c_now)); +          return Clock::now() < t ? cv_status::no_timeout : cv_status::timeout; +        } + +        template <class Clock, class Duration, class Predicate> +        bool +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } + + +        template <class Rep, class Period> +        cv_status +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          system_clock::time_point s_now = system_clock::now(); +          steady_clock::time_point c_now = steady_clock::now(); +          wait_until(lock, s_now + ceil<nanoseconds>(d)); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; + +        } + + +        template <class Rep, class Period, class Predicate> +        bool +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +          while (!pred()) +          { +              if (wait_for(lock, d) == cv_status::timeout) +                  return pred(); +          } +          return true; +        } +#endif + +#define BOOST_THREAD_DEFINES_CONDITION_VARIABLE_NATIVE_HANDLE          typedef pthread_cond_t* native_handle_type;          native_handle_type native_handle()          {              return &cond;          } -        void notify_one(); -        void notify_all(); +        void notify_one() BOOST_NOEXCEPT; +        void notify_all() BOOST_NOEXCEPT; + +#ifdef BOOST_THREAD_USES_CHRONO +        inline void wait_until( +            unique_lock<mutex>& lk, +            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()); +            do_timed_wait(lk, ts); +        } +#endif +        //private: // used by boost::thread::try_join_until + +        inline bool do_timed_wait( +            unique_lock<mutex>& lock, +            struct timespec const &timeout);      }; + +    BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);  } +  #include <boost/config/abi_suffix.hpp>  #endif diff --git a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp index 2a326d7..2c5af92 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/mutex.hpp @@ -1,12 +1,12 @@  #ifndef BOOST_THREAD_PTHREAD_MUTEX_HPP  #define BOOST_THREAD_PTHREAD_MUTEX_HPP  // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 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)  #include <pthread.h> -#include <boost/utility.hpp>  #include <boost/throw_exception.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -14,11 +14,16 @@  #include <boost/thread/xtime.hpp>  #include <boost/assert.hpp>  #include <errno.h> -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #ifdef _POSIX_TIMEOUTS -#if _POSIX_TIMEOUTS >= 0 +#if _POSIX_TIMEOUTS >= 0 && _POSIX_C_SOURCE>=200112L  #define BOOST_PTHREAD_HAS_TIMEDLOCK  #endif  #endif @@ -30,48 +35,70 @@ namespace boost      class mutex      {      private: -        mutex(mutex const&); -        mutex& operator=(mutex const&);                  pthread_mutex_t m;      public: +        BOOST_THREAD_NO_COPYABLE(mutex) +          mutex()          {              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: mutex constructor failed in pthread_mutex_init"));              }          }          ~mutex()          { -            BOOST_VERIFY(!pthread_mutex_destroy(&m)); +            int ret; +            do +            { +                ret = pthread_mutex_destroy(&m); +            } while (ret == EINTR);          } -         +          void lock()          { -            int const res=pthread_mutex_lock(&m); -            if(res) +            int res; +            do +            { +                res = pthread_mutex_lock(&m); +            } while (res == EINTR); +            if (res)              { -                boost::throw_exception(lock_error(res)); +                boost::throw_exception(lock_error(res,"boost: mutex lock failed in pthread_mutex_lock"));              }          }          void unlock()          { -            BOOST_VERIFY(!pthread_mutex_unlock(&m)); +            int ret; +            do +            { +                ret = pthread_mutex_unlock(&m); +            } while (ret == EINTR); +            BOOST_VERIFY(!ret);          } -         +          bool try_lock()          { -            int const res=pthread_mutex_trylock(&m); +            int res; +            do +            { +                res = pthread_mutex_trylock(&m); +            } while (res == EINTR);              if(res && (res!=EBUSY))              { -                boost::throw_exception(lock_error(res)); +                // The following throw_exception has been replaced by an assertion and just return false, +                // as this is an internal error and the user can do nothing with the exception. +                //boost::throw_exception(lock_error(res,"boost: mutex try_lock failed in pthread_mutex_trylock")); +                BOOST_ASSERT_MSG(false ,"boost: mutex try_lock failed in pthread_mutex_trylock"); +                return false;              } -             +              return !res;          } +#define BOOST_THREAD_DEFINES_MUTEX_NATIVE_HANDLE          typedef pthread_mutex_t* native_handle_type;          native_handle_type native_handle()          { @@ -87,28 +114,26 @@ namespace boost      class timed_mutex      {      private: -        timed_mutex(timed_mutex const&); -        timed_mutex& operator=(timed_mutex const&);         -    private:          pthread_mutex_t m;  #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK          pthread_cond_t cond;          bool is_locked;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(timed_mutex)          timed_mutex()          {              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: timed_mutex constructor failed in pthread_mutex_init"));              }  #ifndef BOOST_PTHREAD_HAS_TIMEDLOCK              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: timed_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;  #endif @@ -141,26 +166,23 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         +          bool try_lock()          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } -        bool timed_lock(system_time const & abs_time) -        { -            struct timespec const timeout=detail::get_timespec(abs_time); -            int const res=pthread_mutex_timedlock(&m,&timeout); -            BOOST_ASSERT(!res || res==ETIMEDOUT); -            return !res; -        } -        typedef pthread_mutex_t* native_handle_type; -        native_handle_type native_handle() + +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            return &m; +          int const res=pthread_mutex_timedlock(&m,&timeout); +          BOOST_ASSERT(!res || res==ETIMEDOUT); +          return !res;          } +    public:  #else          void lock() @@ -179,7 +201,7 @@ namespace boost              is_locked=false;              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         +          bool try_lock()          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); @@ -191,9 +213,9 @@ namespace boost              return true;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              while(is_locked)              { @@ -207,8 +229,55 @@ namespace boost              is_locked=true;              return true;          } +    public:  #endif +        bool timed_lock(system_time const & abs_time) +        { +            struct timespec const ts=detail::get_timespec(abs_time); +            return do_try_lock_until(ts); +        } + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_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_lock_until(s_now + ceil<nanoseconds>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +        } +        bool try_lock_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_lock_until(ts); +        } +#endif + +#define BOOST_THREAD_DEFINES_TIMED_MUTEX_NATIVE_HANDLE +        typedef pthread_mutex_t* native_handle_type; +        native_handle_type native_handle() +        { +            return &m; +        } +          typedef unique_lock<timed_mutex> scoped_timed_lock;          typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;          typedef scoped_timed_lock scoped_lock; diff --git a/3rdParty/Boost/src/boost/thread/pthread/once.hpp b/3rdParty/Boost/src/boost/thread/pthread/once.hpp index 6321aa2..02c2732 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/once.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/once.hpp @@ -3,53 +3,86 @@  //  once.hpp  // -//  (C) Copyright 2007-8 Anthony Williams  +//  (C) Copyright 2007-8 Anthony Williams +//  (C) Copyright 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)  #include <boost/thread/detail/config.hpp> -#include <boost/config.hpp> -#include <pthread.h> -#include <boost/assert.hpp> -#include "pthread_mutex_scoped_lock.hpp"  #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> -#include <boost/cstdint.hpp> +#include <boost/thread/detail/delete.hpp> +#include <boost/detail/no_exceptions_support.hpp> +#include <boost/assert.hpp>  #include <boost/config/abi_prefix.hpp> +#include <boost/cstdint.hpp> +#include <pthread.h> +#include <csignal> +  namespace boost  { +#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 + +  namespace thread_detail +  { +//#ifdef SIG_ATOMIC_MAX +//    typedef sig_atomic_t  uintmax_atomic_t; +//    #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C SIG_ATOMIC_MAX +//#else +    typedef unsigned long  uintmax_atomic_t; +    #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(value) value##ul +    #define BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_C2(~0) +//#endif +  } + +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + +  struct once_flag +  { +      BOOST_THREAD_NO_COPYABLE(once_flag) +      BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT +        : epoch(BOOST_ONCE_INITIAL_FLAG_VALUE) +      {} +  private: +      volatile thread_detail::uintmax_atomic_t epoch; +      template<typename Function> +      friend +      void call_once(once_flag& flag,Function f); +  }; + +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 +      struct once_flag      { -        boost::uintmax_t epoch; +      volatile thread_detail::uintmax_atomic_t epoch;      }; +#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} +#endif // BOOST_THREAD_PROVIDES_ONCE_CXX11 +      namespace detail      { -        BOOST_THREAD_DECL boost::uintmax_t& get_once_per_thread_epoch(); -        BOOST_THREAD_DECL extern boost::uintmax_t once_global_epoch; +        BOOST_THREAD_DECL thread_detail::uintmax_atomic_t& get_once_per_thread_epoch(); +        BOOST_THREAD_DECL extern thread_detail::uintmax_atomic_t once_global_epoch;          BOOST_THREAD_DECL extern pthread_mutex_t once_epoch_mutex;          BOOST_THREAD_DECL extern pthread_cond_t once_epoch_cv;      } -     -#define BOOST_ONCE_INITIAL_FLAG_VALUE 0 -#define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE} -      // Based on Mike Burrows fast_pthread_once algorithm as described in      // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2444.html      template<typename Function>      void call_once(once_flag& flag,Function f)      { -        static boost::uintmax_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE; -        static boost::uintmax_t const being_initialized=uninitialized_flag+1; -        boost::uintmax_t const epoch=flag.epoch; -        boost::uintmax_t& this_thread_epoch=detail::get_once_per_thread_epoch(); -         +        static thread_detail::uintmax_atomic_t const uninitialized_flag=BOOST_ONCE_INITIAL_FLAG_VALUE; +        static thread_detail::uintmax_atomic_t const being_initialized=uninitialized_flag+1; +        thread_detail::uintmax_atomic_t const epoch=flag.epoch; +        thread_detail::uintmax_atomic_t& this_thread_epoch=detail::get_once_per_thread_epoch(); +          if(epoch<this_thread_epoch)          {              pthread::pthread_mutex_scoped_lock lk(&detail::once_epoch_mutex); @@ -59,21 +92,18 @@ namespace boost                  if(flag.epoch==uninitialized_flag)                  {                      flag.epoch=being_initialized; -#ifndef BOOST_NO_EXCEPTIONS -                    try +                    BOOST_TRY                      { -#endif                          pthread::pthread_mutex_scoped_unlock relocker(&detail::once_epoch_mutex);                          f(); -#ifndef BOOST_NO_EXCEPTIONS                      } -                    catch(...) +                    BOOST_CATCH (...)                      {                          flag.epoch=uninitialized_flag;                          BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv)); -                        throw; +                        BOOST_RETHROW                      } -#endif +                    BOOST_CATCH_END                      flag.epoch=--detail::once_global_epoch;                      BOOST_VERIFY(!pthread_cond_broadcast(&detail::once_epoch_cv));                  } diff --git a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp index 4158a57..2a6bc7d 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/recursive_mutex.hpp @@ -1,12 +1,12 @@  #ifndef BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP  #define BOOST_THREAD_PTHREAD_RECURSIVE_MUTEX_HPP  // (C) Copyright 2007-8 Anthony Williams +// (C) Copyright 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)  #include <pthread.h> -#include <boost/utility.hpp>  #include <boost/throw_exception.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -17,8 +17,13 @@  #endif  #include <boost/date_time/posix_time/conversion.hpp>  #include <errno.h> -#include "timespec.hpp" -#include "pthread_mutex_scoped_lock.hpp" +#include <boost/thread/pthread/timespec.hpp> +#include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #ifdef _POSIX_TIMEOUTS  #if _POSIX_TIMEOUTS >= 0 @@ -26,7 +31,7 @@  #endif  #endif -#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK) +#if defined(BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)  #define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK  #endif @@ -37,51 +42,50 @@ namespace boost      class recursive_mutex      {      private: -        recursive_mutex(recursive_mutex const&); -        recursive_mutex& operator=(recursive_mutex const&);                  pthread_mutex_t m; -#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE          pthread_cond_t cond;          bool is_locked;          pthread_t owner;          unsigned count;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(recursive_mutex)          recursive_mutex()          { -#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE              pthread_mutexattr_t attr; -             +              int const init_attr_res=pthread_mutexattr_init(&attr);              if(init_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_init"));              }              int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);              if(set_attr_res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_mutex constructor failed in pthread_mutexattr_settype"));              } -             +              int const res=pthread_mutex_init(&m,&attr);              if(res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));              }              BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));  #else              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_mutex constructor failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: recursive_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;              count=0; @@ -90,12 +94,12 @@ namespace boost          ~recursive_mutex()          {              BOOST_VERIFY(!pthread_mutex_destroy(&m)); -#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifndef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE              BOOST_VERIFY(!pthread_cond_destroy(&cond));  #endif          } -#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE +#ifdef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE          void lock()          {              BOOST_VERIFY(!pthread_mutex_lock(&m)); @@ -105,13 +109,14 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         -        bool try_lock() + +        bool try_lock() BOOST_NOEXCEPT          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } +#define BOOST_THREAD_DEFINES_RECURSIVE_MUTEX_NATIVE_HANDLE          typedef pthread_mutex_t* native_handle_type;          native_handle_type native_handle()          { @@ -127,7 +132,7 @@ namespace boost                  ++count;                  return;              } -             +              while(is_locked)              {                  BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); @@ -146,7 +151,7 @@ namespace boost              }              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         +          bool try_lock()          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m); @@ -171,9 +176,6 @@ namespace boost      class recursive_timed_mutex      {      private: -        recursive_timed_mutex(recursive_timed_mutex const&); -        recursive_timed_mutex& operator=(recursive_timed_mutex const&);         -    private:          pthread_mutex_t m;  #ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK          pthread_cond_t cond; @@ -182,40 +184,41 @@ namespace boost          unsigned count;  #endif      public: +        BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)          recursive_timed_mutex()          {  #ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK              pthread_mutexattr_t attr; -             +              int const init_attr_res=pthread_mutexattr_init(&attr);              if(init_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(init_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_init"));              }              int const set_attr_res=pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);              if(set_attr_res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(set_attr_res, "boost:: recursive_timed_mutex constructor failed in pthread_mutexattr_settype"));              } -             +              int const res=pthread_mutex_init(&m,&attr);              if(res)              {                  BOOST_VERIFY(!pthread_mutexattr_destroy(&attr)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));              }              BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));  #else              int const res=pthread_mutex_init(&m,NULL);              if(res)              { -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res, "boost:: recursive_timed_mutex constructor failed in pthread_mutex_init"));              }              int const res2=pthread_cond_init(&cond,NULL);              if(res2)              {                  BOOST_VERIFY(!pthread_mutex_destroy(&m)); -                boost::throw_exception(thread_resource_error()); +                boost::throw_exception(thread_resource_error(res2, "boost:: recursive_timed_mutex constructor failed in pthread_cond_init"));              }              is_locked=false;              count=0; @@ -245,26 +248,22 @@ namespace boost          {              BOOST_VERIFY(!pthread_mutex_unlock(&m));          } -         +          bool try_lock()          {              int const res=pthread_mutex_trylock(&m);              BOOST_ASSERT(!res || res==EBUSY);              return !res;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              int const res=pthread_mutex_timedlock(&m,&timeout);              BOOST_ASSERT(!res || res==ETIMEDOUT);              return !res;          } -        typedef pthread_mutex_t* native_handle_type; -        native_handle_type native_handle() -        { -            return &m; -        } +    public:  #else          void lock() @@ -275,7 +274,7 @@ namespace boost                  ++count;                  return;              } -             +              while(is_locked)              {                  BOOST_VERIFY(!pthread_cond_wait(&cond,&m)); @@ -294,8 +293,8 @@ namespace boost              }              BOOST_VERIFY(!pthread_cond_signal(&cond));          } -         -        bool try_lock() + +        bool try_lock() BOOST_NOEXCEPT          {              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              if(is_locked && !pthread_equal(owner,pthread_self())) @@ -308,9 +307,9 @@ namespace boost              return true;          } -        bool timed_lock(system_time const & abs_time) +    private: +        bool do_try_lock_until(struct timespec const &timeout)          { -            struct timespec const timeout=detail::get_timespec(abs_time);              boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);              if(is_locked && pthread_equal(owner,pthread_self()))              { @@ -331,8 +330,56 @@ namespace boost              owner=pthread_self();              return true;          } +    public: +  #endif +        bool timed_lock(system_time const & abs_time) +        { +            struct timespec const ts=detail::get_timespec(abs_time); +            return do_try_lock_until(ts); +        } + +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_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_lock_until(s_now + ceil<nanoseconds>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<system_clock, nanoseconds> nano_sys_tmpt; +          return try_lock_until(nano_sys_tmpt(ceil<nanoseconds>(t.time_since_epoch()))); +        } +        bool try_lock_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_lock_until(ts); +        } +#endif + +#define BOOST_THREAD_DEFINES_RECURSIVE_TIMED_MUTEX_NATIVE_HANDLE +        typedef pthread_mutex_t* native_handle_type; +        native_handle_type native_handle() +        { +            return &m; +        } +          typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;          typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;          typedef scoped_timed_lock scoped_lock; diff --git a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp index bc26282..cf45188 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/shared_mutex.hpp @@ -2,6 +2,7 @@  #define BOOST_THREAD_PTHREAD_SHARED_MUTEX_HPP  //  (C) Copyright 2006-8 Anthony Williams +//  (C) Copyright 2012 Vicente J. Botet Escriba  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at @@ -12,6 +13,11 @@  #include <boost/thread/mutex.hpp>  #include <boost/thread/condition_variable.hpp>  #include <boost/thread/detail/thread_interruption.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #include <boost/config/abi_prefix.hpp> @@ -27,7 +33,7 @@ namespace boost              bool upgrade;              bool exclusive_waiting_blocked;          }; -         +          state_data state; @@ -41,9 +47,10 @@ namespace boost              exclusive_cond.notify_one();              shared_cond.notify_all();          } -              public: +        BOOST_THREAD_NO_COPYABLE(shared_mutex) +          shared_mutex()          {              state_data state_={0,0,0,0}; @@ -58,7 +65,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.exclusive || state.exclusive_waiting_blocked)              {                  shared_cond.wait(lk); @@ -69,7 +76,7 @@ namespace boost          bool try_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); -                 +              if(state.exclusive || state.exclusive_waiting_blocked)              {                  return false; @@ -85,7 +92,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.exclusive || state.exclusive_waiting_blocked)              {                  if(!shared_cond.timed_wait(lk,timeout)) @@ -102,12 +109,34 @@ namespace boost          {              return timed_lock_shared(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_shared_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          while(state.exclusive || state.exclusive_waiting_blocked) +          { +              if(cv_status::timeout==shared_cond.wait_until(lk,abs_time)) +              { +                  return false; +              } +          } +          ++state.shared_count; +          return true; +        } +#endif          void unlock_shared()          {              boost::mutex::scoped_lock lk(state_change);              bool const last_reader=!--state.shared_count; -                 +              if(last_reader)              {                  if(state.upgrade) @@ -128,7 +157,7 @@ namespace boost          {              boost::this_thread::disable_interruption do_not_disturb;              boost::mutex::scoped_lock lk(state_change); -                 +              while(state.shared_count || state.exclusive)              {                  state.exclusive_waiting_blocked=true; @@ -150,7 +179,7 @@ namespace boost                      if(state.shared_count || state.exclusive)                      {                          state.exclusive_waiting_blocked=false; -                        exclusive_cond.notify_one(); +                        release_waiters();                          return false;                      }                      break; @@ -166,10 +195,41 @@ namespace boost              return timed_lock(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); + +          while(state.shared_count || state.exclusive) +          { +              state.exclusive_waiting_blocked=true; +              if(cv_status::timeout == exclusive_cond.wait_until(lk,abs_time)) +              { +                  if(state.shared_count || state.exclusive) +                  { +                      state.exclusive_waiting_blocked=false; +                      release_waiters(); +                      return false; +                  } +                  break; +              } +          } +          state.exclusive=true; +          return true; +        } +#endif +          bool try_lock()          {              boost::mutex::scoped_lock lk(state_change); -                 +              if(state.shared_count || state.exclusive)              {                  return false; @@ -179,7 +239,7 @@ namespace boost                  state.exclusive=true;                  return true;              } -                 +          }          void unlock() @@ -228,6 +288,33 @@ namespace boost              return timed_lock_upgrade(get_system_time()+relative_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_upgrade_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_upgrade_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_upgrade_until(const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          while(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) +          { +              if(cv_status::timeout == shared_cond.wait_until(lk,abs_time)) +              { +                  if(state.exclusive || state.exclusive_waiting_blocked || state.upgrade) +                  { +                      return false; +                  } +                  break; +              } +          } +          ++state.shared_count; +          state.upgrade=true; +          return true; +        } +#endif          bool try_lock_upgrade()          {              boost::mutex::scoped_lock lk(state_change); @@ -248,14 +335,17 @@ namespace boost              boost::mutex::scoped_lock lk(state_change);              state.upgrade=false;              bool const last_reader=!--state.shared_count; -                 +              if(last_reader)              {                  state.exclusive_waiting_blocked=false;                  release_waiters(); +            } else { +              shared_cond.notify_all();              }          } +        // Upgrade <-> Exclusive          void unlock_upgrade_and_lock()          {              boost::this_thread::disable_interruption do_not_disturb; @@ -278,7 +368,58 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } -         + +        bool try_unlock_upgrade_and_lock() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && state.upgrade +              && state.shared_count==1) +          { +            state.shared_count=0; +            state.exclusive=true; +            state.upgrade=false; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool +        try_unlock_upgrade_and_lock_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_upgrade_and_lock_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool +        try_unlock_upgrade_and_lock_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if (state.shared_count != 1) +          { +              for (;;) +              { +                cv_status status = shared_cond.wait_until(lk,abs_time); +                if (state.shared_count == 1) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=false; +          state.exclusive=true; +          state.exclusive_waiting_blocked=false; +          state.shared_count=0; +          return true; +        } +#endif + +        // Shared <-> Exclusive          void unlock_and_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); @@ -287,7 +428,59 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } -         + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        bool try_unlock_shared_and_lock() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && !state.upgrade +              && state.shared_count==1) +          { +            state.shared_count=0; +            state.exclusive=true; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +            bool +            try_unlock_shared_and_lock_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_shared_and_lock_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +            bool +            try_unlock_shared_and_lock_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if (state.shared_count != 1) +          { +              for (;;) +              { +                cv_status status = shared_cond.wait_until(lk,abs_time); +                if (state.shared_count == 1) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=false; +          state.exclusive=true; +          state.exclusive_waiting_blocked=false; +          state.shared_count=0; +          return true; +        } +#endif +#endif + +        // Shared <-> Upgrade          void unlock_upgrade_and_lock_shared()          {              boost::mutex::scoped_lock lk(state_change); @@ -295,7 +488,62 @@ namespace boost              state.exclusive_waiting_blocked=false;              release_waiters();          } + +#ifdef BOOST_THREAD_PROVIDES_SHARED_MUTEX_UPWARDS_CONVERSIONS +        bool try_unlock_shared_and_lock_upgrade() +        { +          boost::mutex::scoped_lock lk(state_change); +          if(    !state.exclusive +              && !state.exclusive_waiting_blocked +              && !state.upgrade +              ) +          { +            state.upgrade=true; +            return true; +          } +          return false; +        } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +            bool +            try_unlock_shared_and_lock_upgrade_for( +                                const chrono::duration<Rep, Period>& rel_time) +        { +          return try_unlock_shared_and_lock_upgrade_until( +                                 chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +            bool +            try_unlock_shared_and_lock_upgrade_until( +                          const chrono::time_point<Clock, Duration>& abs_time) +        { +          boost::this_thread::disable_interruption do_not_disturb; +          boost::mutex::scoped_lock lk(state_change); +          if(    state.exclusive +              || state.exclusive_waiting_blocked +              || state.upgrade +              ) +          { +              for (;;) +              { +                cv_status status = exclusive_cond.wait_until(lk,abs_time); +                if(    ! state.exclusive +                    && ! state.exclusive_waiting_blocked +                    && ! state.upgrade +                    ) +                  break; +                if(status == cv_status::timeout) +                  return false; +              } +          } +          state.upgrade=true; +          return true; +        } +#endif +#endif      }; + +    typedef shared_mutex upgrade_mutex;  }  #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 1bee28b..db4e09f 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -4,24 +4,77 @@  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  // (C) Copyright 2007 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  #include <boost/thread/detail/config.hpp>  #include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/pthread/condition_variable_fwd.hpp> +  #include <boost/shared_ptr.hpp>  #include <boost/enable_shared_from_this.hpp> -#include <boost/thread/mutex.hpp>  #include <boost/optional.hpp> -#include <pthread.h>  #include <boost/assert.hpp> -#include "condition_variable_fwd.hpp" +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif +  #include <map> +#include <vector> +#include <utility> + +#include <pthread.h> +#include <unistd.h>  #include <boost/config/abi_prefix.hpp>  namespace boost  { +    class thread_attributes { +    public: +        thread_attributes() BOOST_NOEXCEPT { +            int res = pthread_attr_init(&val_); +            BOOST_VERIFY(!res && "pthread_attr_init failed"); +        } +        ~thread_attributes() { +          int res = pthread_attr_destroy(&val_); +          BOOST_VERIFY(!res && "pthread_attr_destroy failed"); +        } +        // stack +        void set_stack_size(std::size_t size) BOOST_NOEXCEPT { +          if (size==0) return; +          std::size_t page_size = getpagesize(); +#ifdef PTHREAD_STACK_MIN +          if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN; +#endif +          size = ((size+page_size-1)/page_size)*page_size; +          int res = pthread_attr_setstacksize(&val_, size); +          BOOST_VERIFY(!res && "pthread_attr_setstacksize failed"); +        } + +        std::size_t get_stack_size() const BOOST_NOEXCEPT { +            std::size_t size; +            int res = pthread_attr_getstacksize(&val_, &size); +            BOOST_VERIFY(!res && "pthread_attr_getstacksize failed"); +            return size; +        } +#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE + +        typedef pthread_attr_t native_handle_type; +        native_handle_type* native_handle() BOOST_NOEXCEPT { +          return &val_; +        } +        const native_handle_type* native_handle() const BOOST_NOEXCEPT { +          return &val_; +        } + +    private: +        pthread_attr_t val_; +    }; +      class thread; -     +      namespace detail      {          struct tss_cleanup_function; @@ -39,7 +92,7 @@ namespace boost          struct thread_data_base;          typedef boost::shared_ptr<thread_data_base> thread_data_ptr; -         +          struct BOOST_THREAD_DECL thread_data_base:              enable_shared_from_this<thread_data_base>          { @@ -58,19 +111,28 @@ namespace boost              bool interrupt_requested;              pthread_mutex_t* cond_mutex;              pthread_cond_t* current_cond; +            typedef std::vector<std::pair<condition_variable*, mutex*> +            //, hidden_allocator<std::pair<condition_variable*, mutex*> > +            > notify_list_t; +            notify_list_t notify;              thread_data_base():                  done(false),join_started(false),joined(false),                  thread_exit_callbacks(0),                  interrupt_enabled(true),                  interrupt_requested(false), -                current_cond(0) +                current_cond(0), +                notify()              {}              virtual ~thread_data_base();              typedef pthread_t native_handle_type;              virtual void run()=0; +            void notify_all_at_thread_exit(condition_variable* cv, mutex* m) +            { +              notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); +            }          };          BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); @@ -83,13 +145,15 @@ namespace boost              void check_for_interruption()              { +#ifndef BOOST_NO_EXCEPTIONS                  if(thread_info->interrupt_requested)                  {                      thread_info->interrupt_requested=false; -                    throw thread_interrupted(); +                    throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected                  } +#endif              } -             +              void operator=(interruption_checker&);          public:              explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): @@ -128,15 +192,66 @@ namespace boost      namespace this_thread      { -        void BOOST_THREAD_DECL yield(); -         -        void BOOST_THREAD_DECL sleep(system_time const& abs_time); -         +#ifdef BOOST_THREAD_USES_CHRONO +        inline +        void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) +        { +            using namespace chrono; +            boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); + +            if(thread_info) +            { +              unique_lock<mutex> lk(thread_info->sleep_mutex); +              while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {} +            } +            else +            { +              if (ns >= nanoseconds::zero()) +              { + +  #   if defined(BOOST_HAS_PTHREAD_DELAY_NP) +                timespec ts; +                ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count()); +                ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count()); +                BOOST_VERIFY(!pthread_delay_np(&ts)); +  #   elif defined(BOOST_HAS_NANOSLEEP) +                timespec ts; +                ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count()); +                ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count()); +                //  nanosleep takes a timespec that is an offset, not +                //  an absolute time. +                nanosleep(&ts, 0); +  #   else +                mutex mx; +                mutex::scoped_lock lock(mx); +                condition_variable cond; +                cond.wait_for(lock, ns); +  #   endif +              } +            } +        } +#endif +        void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT; + +#ifdef __DECXXX +        /// Workaround of DECCXX issue of incorrect template substitution          template<typename TimeDuration>          inline void sleep(TimeDuration const& rel_time)          {              this_thread::sleep(get_system_time()+rel_time);          } + +        template<> +        void BOOST_THREAD_DECL sleep(system_time const& abs_time); +#else +        void BOOST_THREAD_DECL sleep(system_time const& abs_time); + +        template<typename TimeDuration> +        inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) +        { +            this_thread::sleep(get_system_time()+rel_time); +        } +#endif      }  } diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp index 737c298..7828318 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_heap_alloc.hpp @@ -17,7 +17,7 @@ namespace boost              return new T();          } -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES          template<typename T,typename A1>          inline T* heap_new(A1&& a1)          { @@ -72,7 +72,7 @@ namespace boost          {              return heap_new_impl<T,A1&>(a1);          } -         +          template<typename T,typename A1,typename A2>          inline T* heap_new(A1 const& a1,A2 const& a2)          { @@ -218,8 +218,8 @@ namespace boost          {              return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);          } -         -#endif         + +#endif          template<typename T>          inline void heap_delete(T* data)          { diff --git a/3rdParty/Boost/src/boost/thread/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/shared_mutex.hpp index 51eda0d..e85e269 100644 --- a/3rdParty/Boost/src/boost/thread/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/shared_mutex.hpp @@ -3,15 +3,20 @@  //  shared_mutex.hpp  // -//  (C) Copyright 2007 Anthony Williams  +//  (C) Copyright 2007 Anthony Williams +//  (C) Copyright 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) -#include <boost/thread/detail/platform.hpp> +#include <boost/thread/detail/config.hpp>  #if defined(BOOST_THREAD_PLATFORM_WIN32) +#if defined(BOOST_THREAD_PROVIDES_GENERIC_SHARED_MUTEX_ON_WIN) +#include <boost/thread/pthread/shared_mutex.hpp> +#else  #include <boost/thread/win32/shared_mutex.hpp> +#endif  #elif defined(BOOST_THREAD_PLATFORM_PTHREAD)  #include <boost/thread/pthread/shared_mutex.hpp>  #else diff --git a/3rdParty/Boost/src/boost/thread/thread.hpp b/3rdParty/Boost/src/boost/thread/thread.hpp index fdfdadc..ee15c6e 100644 --- a/3rdParty/Boost/src/boost/thread/thread.hpp +++ b/3rdParty/Boost/src/boost/thread/thread.hpp @@ -3,7 +3,7 @@  //  thread.hpp  // -//  (C) Copyright 2007-8 Anthony Williams  +//  (C) Copyright 2007-8 Anthony Williams  //  //  Distributed under the Boost Software License, Version 1.0. (See  //  accompanying file LICENSE_1_0.txt or copy at @@ -22,6 +22,7 @@  #include <boost/thread/detail/thread.hpp>  #include <boost/thread/detail/thread_interruption.hpp>  #include <boost/thread/detail/thread_group.hpp> +#include <boost/thread/v2/thread.hpp>  #endif diff --git a/3rdParty/Boost/src/boost/thread/v2/thread.hpp b/3rdParty/Boost/src/boost/thread/v2/thread.hpp new file mode 100644 index 0000000..d686c5f --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/v2/thread.hpp @@ -0,0 +1,56 @@ +// 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 2011 Vicente J. Botet Escriba + +#ifndef BOOST_THREAD_V2_THREAD_HPP +#define BOOST_THREAD_V2_THREAD_HPP + +#include <boost/thread/detail/config.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif +#include <boost/thread/condition_variable.hpp> +#include <boost/thread/locks.hpp> + +namespace boost +{ +  namespace this_thread +  { + +#ifdef BOOST_THREAD_USES_CHRONO + +    template <class Rep, class Period> +    void sleep_for(const chrono::duration<Rep, Period>& d) +    { +      using namespace chrono; +      nanoseconds ns = duration_cast<nanoseconds> (d); +      if (ns < d) ++ns; +      sleep_for(ns); +    } + +    template <class Clock, class Duration> +    void sleep_until(const chrono::time_point<Clock, Duration>& t) +    { +      using namespace chrono; +      mutex mut; +      condition_variable cv; +      unique_lock<mutex> lk(mut); +      while (Clock::now() < t) +        cv.wait_until(lk, t); +    } + +    template <class Duration> +    inline BOOST_SYMBOL_VISIBLE +    void sleep_until(const chrono::time_point<chrono::steady_clock, Duration>& t) +    { +      using namespace chrono; +      sleep_for(t - steady_clock::now()); +    } + +#endif +  } +} + + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp index 05eb8d7..e259121 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp @@ -3,14 +3,19 @@  //  basic_recursive_mutex.hpp  // -//  (C) Copyright 2006-8 Anthony Williams  +//  (C) Copyright 2006-8 Anthony Williams +//  (C) Copyright 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) -#include "thread_primitives.hpp" -#include "basic_timed_mutex.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/basic_timed_mutex.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif  #include <boost/config/abi_prefix.hpp> @@ -37,12 +42,12 @@ namespace boost                  mutex.destroy();              } -            bool try_lock() +            bool try_lock() BOOST_NOEXCEPT              {                  long const current_thread_id=win32::GetCurrentThreadId();                  return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id);              } -             +              void lock()              {                  long const current_thread_id=win32::GetCurrentThreadId(); @@ -64,6 +69,20 @@ namespace boost                  return timed_lock(get_system_time()+timeout);              } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +                long const current_thread_id=win32::GetCurrentThreadId(); +                return try_recursive_lock(current_thread_id) || try_timed_lock_for(current_thread_id,rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_until(const chrono::time_point<Clock, Duration>& t) +        { +                long const current_thread_id=win32::GetCurrentThreadId(); +                return try_recursive_lock(current_thread_id) || try_timed_lock_until(current_thread_id,t); +        } +#endif              void unlock()              {                  if(!--recursion_count) @@ -74,7 +93,7 @@ namespace boost              }          private: -            bool try_recursive_lock(long current_thread_id) +            bool try_recursive_lock(long current_thread_id) BOOST_NOEXCEPT              {                  if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id)                  { @@ -83,8 +102,8 @@ namespace boost                  }                  return false;              } -             -            bool try_basic_lock(long current_thread_id) + +            bool try_basic_lock(long current_thread_id) BOOST_NOEXCEPT              {                  if(mutex.try_lock())                  { @@ -94,7 +113,7 @@ namespace boost                  }                  return false;              } -             +              bool try_timed_lock(long current_thread_id,::boost::system_time const& target)              {                  if(mutex.timed_lock(target)) @@ -105,7 +124,28 @@ namespace boost                  }                  return false;              } -             +            template <typename TP> +            bool try_timed_lock_until(long current_thread_id,TP const& target) +            { +                if(mutex.try_lock_until(target)) +                { +                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); +                    recursion_count=1; +                    return true; +                } +                return false; +            } +            template <typename D> +            bool try_timed_lock_for(long current_thread_id,D const& target) +            { +                if(mutex.try_lock_for(target)) +                { +                    BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); +                    recursion_count=1; +                    return true; +                } +                return false; +            }          };          typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex; diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp index 7c6797d..6a43077 100644 --- a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp @@ -3,19 +3,23 @@  //  basic_timed_mutex_win32.hpp  // -//  (C) Copyright 2006-8 Anthony Williams  +//  (C) Copyright 2006-8 Anthony Williams +//  (C) Copyright 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)  #include <boost/assert.hpp> -#include "thread_primitives.hpp" -#include "interlocked_read.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/interlocked_read.hpp>  #include <boost/thread/thread_time.hpp>  #include <boost/thread/xtime.hpp>  #include <boost/detail/interlocked.hpp> - +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif  #include <boost/config/abi_prefix.hpp>  namespace boost @@ -52,13 +56,13 @@ namespace boost                      win32::CloseHandle(old_event);                  }              } -             -           -            bool try_lock() + + +            bool try_lock() BOOST_NOEXCEPT              {                  return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit);              } -             +              void lock()              {                  if(try_lock()) @@ -112,8 +116,8 @@ namespace boost                      old_count=current;                  }              } -             -             + +              bool timed_lock(::boost::system_time const& wait_until)              {                  if(try_lock()) @@ -143,6 +147,7 @@ namespace boost                  return true;              } +              template<typename Duration>              bool timed_lock(Duration const& timeout)              { @@ -154,6 +159,59 @@ namespace boost                  return timed_lock(system_time(timeout));              } +#ifdef BOOST_THREAD_USES_CHRONO +            template <class Rep, class Period> +            bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +            { +              return try_lock_until(chrono::steady_clock::now() + rel_time); +            } +            template <class Clock, class Duration> +            bool try_lock_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_lock_until(s_now + ceil<system_clock::duration>(t - c_now)); +            } +            template <class Duration> +            bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +            { +              using namespace chrono; +              typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; +              return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); +            } +            bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) +            { +              if(try_lock()) +              { +                  return true; +              } +              long old_count=active_count; +              mark_waiting_and_try_lock(old_count); + +              if(old_count&lock_flag_value) +              { +                  bool lock_acquired=false; +                  void* const sem=get_event(); + +                  do +                  { +                      chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); + +                      if(win32::WaitForSingleObject(sem,static_cast<unsigned long>(rel_time.count()))!=0) +                      { +                          BOOST_INTERLOCKED_DECREMENT(&active_count); +                          return false; +                      } +                      clear_waiting_and_try_lock(old_count); +                      lock_acquired=!(old_count&lock_flag_value); +                  } +                  while(!lock_acquired); +              } +              return true; +            } +#endif +              void unlock()              {                  long const offset=lock_flag_value; @@ -171,7 +229,7 @@ namespace boost              void* get_event()              {                  void* current_event=::boost::detail::interlocked_read_acquire(&event); -                 +                  if(!current_event)                  {                      void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset); @@ -196,9 +254,9 @@ namespace boost                  }                  return current_event;              } -             +          }; -         +      }  } diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp index 6e676b4..4c893ad 100644 --- a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp @@ -4,18 +4,28 @@  // 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 +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/thread_data.hpp> +#include <boost/thread/win32/thread_data.hpp> +#include <boost/thread/win32/interlocked_read.hpp> +#include <boost/thread/cv_status.hpp> +#include <boost/thread/xtime.hpp>  #include <boost/thread/mutex.hpp> -#include "thread_primitives.hpp" -#include <limits.h> +#include <boost/thread/thread_time.hpp> +  #include <boost/assert.hpp> +#include <boost/intrusive_ptr.hpp> + +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif + +#include <limits.h>  #include <algorithm> -#include <boost/thread/thread.hpp> -#include <boost/thread/thread_time.hpp> -#include "interlocked_read.hpp" -#include <boost/thread/xtime.hpp>  #include <vector> -#include <boost/intrusive_ptr.hpp>  #include <boost/config/abi_prefix.hpp> @@ -26,7 +36,7 @@ namespace boost          class basic_cv_list_entry;          void intrusive_ptr_add_ref(basic_cv_list_entry * p);          void intrusive_ptr_release(basic_cv_list_entry * p); -         +          class basic_cv_list_entry          {          private: @@ -36,10 +46,8 @@ namespace boost              bool notified;              long references; -            basic_cv_list_entry(basic_cv_list_entry&); -            void operator=(basic_cv_list_entry&); -                      public: +            BOOST_THREAD_NO_COPYABLE(basic_cv_list_entry)              explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_):                  semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)),                  wake_sem(wake_sem_.duplicate()), @@ -55,7 +63,7 @@ namespace boost              {                  BOOST_INTERLOCKED_INCREMENT(&waiters);              } -             +              void remove_waiter()              {                  BOOST_INTERLOCKED_DECREMENT(&waiters); @@ -77,9 +85,9 @@ namespace boost                  return notified;              } -            bool wait(timeout wait_until) +            bool wait(timeout abs_time)              { -                return this_thread::interruptible_wait(semaphore,wait_until); +                return this_thread::interruptible_wait(semaphore,abs_time);              }              bool woken() @@ -97,7 +105,7 @@ namespace boost          {              BOOST_INTERLOCKED_INCREMENT(&p->references);          } -             +          inline void intrusive_ptr_release(basic_cv_list_entry * p)          {              if(!BOOST_INTERLOCKED_DECREMENT(&p->references)) @@ -125,13 +133,14 @@ namespace boost                  detail::interlocked_write_release(&total_count,total_count-count_to_wake);                  detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0);              } -             +              template<typename lock_type>              struct relocker              { +                BOOST_THREAD_NO_COPYABLE(relocker)                  lock_type& lock;                  bool unlocked; -                 +                  relocker(lock_type& lock_):                      lock(lock_),unlocked(false)                  {} @@ -146,13 +155,10 @@ namespace boost                      {                          lock.lock();                      } -                     +                  } -            private: -                relocker(relocker&); -                void operator=(relocker&);              }; -             +              entry_ptr get_wait_entry()              { @@ -177,37 +183,37 @@ namespace boost                      return generations.back();                  }              } -             +              struct entry_manager              {                  entry_ptr const entry; -                     + +                BOOST_THREAD_NO_COPYABLE(entry_manager)                  entry_manager(entry_ptr const& entry_):                      entry(entry_)                  {} -                     +                  ~entry_manager()                  { +                  if(! entry->is_notified()) +                  {                      entry->remove_waiter(); +                  }                  }                  list_entry* operator->()                  {                      return entry.get();                  } - -            private: -                void operator=(entry_manager&); -                entry_manager(entry_manager&);              }; -                 +          protected:              template<typename lock_type> -            bool do_wait(lock_type& lock,timeout wait_until) +            bool do_wait(lock_type& lock,timeout abs_time)              {                  relocker<lock_type> locker(lock); -                 +                  entry_manager entry(get_wait_entry());                  locker.unlock(); @@ -215,27 +221,27 @@ namespace boost                  bool woken=false;                  while(!woken)                  { -                    if(!entry->wait(wait_until)) +                    if(!entry->wait(abs_time))                      {                          return false;                      } -                 +                      woken=entry->woken();                  }                  return woken;              }              template<typename lock_type,typename predicate_type> -            bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred) +            bool do_wait(lock_type& m,timeout const& abs_time,predicate_type pred)              {                  while (!pred())                  { -                    if(!do_wait(m, wait_until)) +                    if(!do_wait(m, abs_time))                          return pred();                  }                  return true;              } -         +              basic_condition_variable(const basic_condition_variable& other);              basic_condition_variable& operator=(const basic_condition_variable& other); @@ -243,11 +249,11 @@ namespace boost              basic_condition_variable():                  total_count(0),active_generation_count(0),wake_sem(0)              {} -             +              ~basic_condition_variable()              {} -            void notify_one() +            void notify_one() BOOST_NOEXCEPT              {                  if(detail::interlocked_read_acquire(&total_count))                  { @@ -267,8 +273,8 @@ namespace boost                      generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end());                  }              } -         -            void notify_all() + +            void notify_all() BOOST_NOEXCEPT              {                  if(detail::interlocked_read_acquire(&total_count))                  { @@ -288,23 +294,21 @@ namespace boost                      wake_sem=detail::win32::handle(0);                  }              } -         +          };      }      class condition_variable:          private detail::basic_condition_variable      { -    private: -        condition_variable(condition_variable&); -        void operator=(condition_variable&);      public: +        BOOST_THREAD_NO_COPYABLE(condition_variable)          condition_variable()          {} -         +          using detail::basic_condition_variable::notify_one;          using detail::basic_condition_variable::notify_all; -         +          void wait(unique_lock<mutex>& m)          {              do_wait(m,detail::timeout::sentinel()); @@ -315,16 +319,16 @@ namespace boost          {              while(!pred()) wait(m);          } -         -        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) + +        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time)          { -            return do_wait(m,wait_until); +            return do_wait(m,abs_time);          } -        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until) +        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time)          { -            return do_wait(m,system_time(wait_until)); +            return do_wait(m,system_time(abs_time));          }          template<typename duration_type>          bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) @@ -333,35 +337,85 @@ namespace boost          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) +        bool timed_wait(unique_lock<mutex>& m,boost::system_time const& abs_time,predicate_type pred)          { -            return do_wait(m,wait_until,pred); +            return do_wait(m,abs_time,pred);          }          template<typename predicate_type> -        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred) +        bool timed_wait(unique_lock<mutex>& m,boost::xtime const& abs_time,predicate_type pred)          { -            return do_wait(m,system_time(wait_until),pred); +            return do_wait(m,system_time(abs_time),pred);          }          template<typename duration_type,typename predicate_type>          bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred)          {              return do_wait(m,wait_duration.total_milliseconds(),pred);          } + +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class Clock, class Duration> +        cv_status +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); +          return Clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class Rep, class Period> +        cv_status +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          steady_clock::time_point c_now = steady_clock::now(); +          do_wait(lock, ceil<milliseconds>(d).count()); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; +        } + +        template <class Clock, class Duration, class Predicate> +        bool +        wait_until( +                unique_lock<mutex>& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } +        template <class Rep, class Period, class Predicate> +        bool +        wait_for( +                unique_lock<mutex>& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +            return wait_until(lock, chrono::steady_clock::now() + d, pred); +        } +#endif      }; -     +      class condition_variable_any:          private detail::basic_condition_variable      { -    private: -        condition_variable_any(condition_variable_any&); -        void operator=(condition_variable_any&);      public: +        BOOST_THREAD_NO_COPYABLE(condition_variable_any)          condition_variable_any()          {} -         +          using detail::basic_condition_variable::notify_one;          using detail::basic_condition_variable::notify_all; -         +          template<typename lock_type>          void wait(lock_type& m)          { @@ -373,17 +427,17 @@ namespace boost          {              while(!pred()) wait(m);          } -         +          template<typename lock_type> -        bool timed_wait(lock_type& m,boost::system_time const& wait_until) +        bool timed_wait(lock_type& m,boost::system_time const& abs_time)          { -            return do_wait(m,wait_until); +            return do_wait(m,abs_time);          }          template<typename lock_type> -        bool timed_wait(lock_type& m,boost::xtime const& wait_until) +        bool timed_wait(lock_type& m,boost::xtime const& abs_time)          { -            return do_wait(m,system_time(wait_until)); +            return do_wait(m,system_time(abs_time));          }          template<typename lock_type,typename duration_type> @@ -393,15 +447,15 @@ namespace boost          }          template<typename lock_type,typename predicate_type> -        bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) +        bool timed_wait(lock_type& m,boost::system_time const& abs_time,predicate_type pred)          { -            return do_wait(m,wait_until,pred); +            return do_wait(m,abs_time,pred);          }          template<typename lock_type,typename predicate_type> -        bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred) +        bool timed_wait(lock_type& m,boost::xtime const& abs_time,predicate_type pred)          { -            return do_wait(m,system_time(wait_until),pred); +            return do_wait(m,system_time(abs_time),pred);          }          template<typename lock_type,typename duration_type,typename predicate_type> @@ -409,8 +463,61 @@ namespace boost          {              return do_wait(m,wait_duration.total_milliseconds(),pred);          } +#ifdef BOOST_THREAD_USES_CHRONO + +        template <class lock_type, class Clock, class Duration> +        cv_status +        wait_until( +                lock_type& lock, +                const chrono::time_point<Clock, Duration>& t) +        { +          using namespace chrono; +          do_wait(lock, ceil<milliseconds>(t-Clock::now()).count()); +          return Clock::now() < t ? cv_status::no_timeout : +                                             cv_status::timeout; +        } + +        template <class lock_type,  class Rep, class Period> +        cv_status +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d) +        { +          using namespace chrono; +          steady_clock::time_point c_now = steady_clock::now(); +          do_wait(lock, ceil<milliseconds>(d).count()); +          return steady_clock::now() - c_now < d ? cv_status::no_timeout : +                                                   cv_status::timeout; +        } + +        template <class lock_type, class Clock, class Duration, class Predicate> +        bool +        wait_until( +                lock_type& lock, +                const chrono::time_point<Clock, Duration>& t, +                Predicate pred) +        { +            while (!pred()) +            { +                if (wait_until(lock, t) == cv_status::timeout) +                    return pred(); +            } +            return true; +        } + +        template <class lock_type, class Rep, class Period, class Predicate> +        bool +        wait_for( +                lock_type& lock, +                const chrono::duration<Rep, Period>& d, +                Predicate pred) +        { +            return wait_until(lock, chrono::steady_clock::now() + d, pred); +        } +#endif      }; +        BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);  }  #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp index 133fb6f..4a96998 100644 --- a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp @@ -3,13 +3,15 @@  //  interlocked_read_win32.hpp  // -//  (C) Copyright 2005-8 Anthony Williams  +//  (C) Copyright 2005-8 Anthony Williams +//  (C) Copyright 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)  #include <boost/detail/interlocked.hpp> +#include <boost/thread/detail/config.hpp>  #include <boost/config/abi_prefix.hpp> @@ -22,25 +24,25 @@ namespace boost  {      namespace detail      { -        inline long interlocked_read_acquire(long volatile* x) +        inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT          {              long const res=*x;              _ReadWriteBarrier();              return res;          } -        inline void* interlocked_read_acquire(void* volatile* x) +        inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT          {              void* const res=*x;              _ReadWriteBarrier();              return res;          } -        inline void interlocked_write_release(long volatile* x,long value) +        inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT          {              _ReadWriteBarrier();              *x=value;          } -        inline void interlocked_write_release(void* volatile* x,void* value) +        inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT          {              _ReadWriteBarrier();              *x=value; @@ -54,19 +56,19 @@ namespace boost  {      namespace detail      { -        inline long interlocked_read_acquire(long volatile* x) +        inline long interlocked_read_acquire(long volatile* x) BOOST_NOEXCEPT          {              return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0);          } -        inline void* interlocked_read_acquire(void* volatile* x) +        inline void* interlocked_read_acquire(void* volatile* x) BOOST_NOEXCEPT          {              return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0);          } -        inline void interlocked_write_release(long volatile* x,long value) +        inline void interlocked_write_release(long volatile* x,long value) BOOST_NOEXCEPT          {              BOOST_INTERLOCKED_EXCHANGE(x,value);          } -        inline void interlocked_write_release(void* volatile* x,void* value) +        inline void interlocked_write_release(void* volatile* x,void* value) BOOST_NOEXCEPT          {              BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value);          } diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp index d59fbfa..85a00e2 100644 --- a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp @@ -1,12 +1,12 @@  #ifndef BOOST_THREAD_WIN32_MUTEX_HPP  #define BOOST_THREAD_WIN32_MUTEX_HPP  // (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 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) -#include "basic_timed_mutex.hpp" -#include <boost/utility.hpp> +#include <boost/thread/win32/basic_timed_mutex.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -22,10 +22,8 @@ namespace boost      class mutex:          public ::boost::detail::underlying_mutex      { -    private: -        mutex(mutex const&); -        mutex& operator=(mutex const&);      public: +        BOOST_THREAD_NO_COPYABLE(mutex)          mutex()          {              initialize(); @@ -44,10 +42,8 @@ namespace boost      class timed_mutex:          public ::boost::detail::basic_timed_mutex      { -    private: -        timed_mutex(timed_mutex const&); -        timed_mutex& operator=(timed_mutex const&);      public: +        BOOST_THREAD_NO_COPYABLE(timed_mutex)          timed_mutex()          {              initialize(); diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp index e1b1843..3066b50 100644 --- a/3rdParty/Boost/src/boost/thread/win32/once.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -3,8 +3,9 @@  //  once.hpp  // -//  (C) Copyright 2005-7 Anthony Williams  +//  (C) Copyright 2005-7 Anthony Williams  //  (C) Copyright 2005 John Maddock +//  (C) Copyright 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 @@ -30,6 +31,25 @@ namespace std  namespace boost  { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + +  struct once_flag +  { +      BOOST_THREAD_NO_COPYABLE(once_flag) +      BOOST_CONSTEXPR once_flag() BOOST_NOEXCEPT +        : status(0), count(0) +      {} +  private: +      long status; +      long count; +      template<typename Function> +      friend +      void call_once(once_flag& flag,Function f); +  }; + +#define BOOST_ONCE_INIT once_flag() +#else // BOOST_THREAD_PROVIDES_ONCE_CXX11 +      struct once_flag      {          long status; @@ -37,6 +57,7 @@ namespace boost      };  #define BOOST_ONCE_INIT {0,0} +#endif  // BOOST_THREAD_PROVIDES_ONCE_CXX11      namespace detail      { @@ -71,29 +92,29 @@ namespace boost  #else              static const once_char_type fixed_mutex_name[]="Local\\{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag";  #endif -            BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==  +            BOOST_STATIC_ASSERT(sizeof(fixed_mutex_name) ==                                  (sizeof(once_char_type)*(once_mutex_name_fixed_length+1))); -             +              std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); -            detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),  +            detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address),                                    mutex_name + once_mutex_name_fixed_length); -            detail::int_to_string(win32::GetCurrentProcessId(),  +            detail::int_to_string(win32::GetCurrentProcessId(),                                    mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2);          } -                         +          inline void* open_once_event(once_char_type* mutex_name,void* flag_address)          {              if(!*mutex_name)              {                  name_once_mutex(mutex_name,flag_address);              } -             -#ifdef BOOST_NO_ANSI_APIS                         + +#ifdef BOOST_NO_ANSI_APIS              return ::boost::detail::win32::OpenEventW(  #else              return ::boost::detail::win32::OpenEventA(  #endif -                ::boost::detail::win32::synchronize |  +                ::boost::detail::win32::synchronize |                  ::boost::detail::win32::event_modify_state,                  false,                  mutex_name); @@ -105,7 +126,7 @@ namespace boost              {                  name_once_mutex(mutex_name,flag_address);              } -#ifdef BOOST_NO_ANSI_APIS                         +#ifdef BOOST_NO_ANSI_APIS              return ::boost::detail::win32::CreateEventW(  #else              return ::boost::detail::win32::CreateEventA( @@ -115,7 +136,7 @@ namespace boost                  mutex_name);          }      } -     +      template<typename Function>      void call_once(once_flag& flag,Function f) @@ -136,7 +157,9 @@ namespace boost              status=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&flag.status,running_value,0);              if(!status)              { -                try +#ifndef BOOST_NO_EXCEPTIONS +                try // BOOST_NO_EXCEPTIONS protected +#endif                  {                      if(!event_handle)                      { @@ -153,7 +176,7 @@ namespace boost                          counted=true;                      }                      BOOST_INTERLOCKED_EXCHANGE(&flag.status,function_complete_flag_value); -                    if(!event_handle &&  +                    if(!event_handle &&                         (::boost::detail::interlocked_read_acquire(&flag.count)>1))                      {                          event_handle=detail::create_once_event(mutex_name,&flag); @@ -164,7 +187,8 @@ namespace boost                      }                      break;                  } -                catch(...) +#ifndef BOOST_NO_EXCEPTIONS +                catch(...) // BOOST_NO_EXCEPTIONS protected                  {                      BOOST_INTERLOCKED_EXCHANGE(&flag.status,0);                      if(!event_handle) @@ -175,8 +199,9 @@ namespace boost                      {                          ::boost::detail::win32::SetEvent(event_handle);                      } -                    throw; +                    throw; // BOOST_NO_EXCEPTIONS protected                  } +#endif              }              if(!counted) diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp index e83d3bc..5144e77 100644 --- a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp @@ -3,15 +3,14 @@  //  recursive_mutex.hpp  // -//  (C) Copyright 2006-7 Anthony Williams  +//  (C) Copyright 2006-7 Anthony Williams  //  //  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) -#include <boost/utility.hpp> -#include "basic_recursive_mutex.hpp" +#include <boost/thread/win32/basic_recursive_mutex.hpp>  #include <boost/thread/exceptions.hpp>  #include <boost/thread/locks.hpp> @@ -22,10 +21,8 @@ namespace boost      class recursive_mutex:          public ::boost::detail::basic_recursive_mutex      { -    private: -        recursive_mutex(recursive_mutex const&); -        recursive_mutex& operator=(recursive_mutex const&);              public: +        BOOST_THREAD_NO_COPYABLE(recursive_mutex)          recursive_mutex()          {              ::boost::detail::basic_recursive_mutex::initialize(); @@ -44,10 +41,8 @@ namespace boost      class recursive_timed_mutex:          public ::boost::detail::basic_recursive_timed_mutex      { -    private: -        recursive_timed_mutex(recursive_timed_mutex const&); -        recursive_timed_mutex& operator=(recursive_timed_mutex const&);              public: +        BOOST_THREAD_NO_COPYABLE(recursive_timed_mutex)          recursive_timed_mutex()          {              ::boost::detail::basic_recursive_timed_mutex::initialize(); diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp index 58fc622..fef2d5b 100644 --- a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp @@ -2,6 +2,7 @@  #define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP  //  (C) Copyright 2006-8 Anthony Williams +//  (C) Copyright 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 @@ -12,8 +13,12 @@  #include <boost/thread/win32/thread_primitives.hpp>  #include <boost/static_assert.hpp>  #include <limits.h> -#include <boost/utility.hpp>  #include <boost/thread/thread_time.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#include <boost/chrono/ceil.hpp> +#endif +#include <boost/thread/detail/delete.hpp>  #include <boost/config/abi_prefix.hpp> @@ -22,9 +27,6 @@ namespace boost      class shared_mutex      {      private: -        shared_mutex(shared_mutex const&); -        shared_mutex& operator=(shared_mutex const&);         -    private:          struct state_data          {              unsigned shared_count:11, @@ -39,7 +41,7 @@ namespace boost                  return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs);              }          }; -         +          template<typename T>          T interlocked_compare_exchange(T* target,T new_value,T comparand) @@ -67,20 +69,32 @@ namespace boost              {                  BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[exclusive_sem],1,0)!=0);              } -                         +              if(old_state.shared_waiting || old_state.exclusive_waiting)              {                  BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0);              }          } -         +      public: +        BOOST_THREAD_NO_COPYABLE(shared_mutex)          shared_mutex()          {              semaphores[unlock_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); -            semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore(0,LONG_MAX); -            upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); +            semaphores[exclusive_sem]=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); +            if (!semaphores[exclusive_sem]) +            { +              detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); +              boost::throw_exception(thread_resource_error()); +            } +            upgrade_sem=detail::win32::create_anonymous_semaphore_nothrow(0,LONG_MAX); +            if (!upgrade_sem) +            { +              detail::win32::release_semaphore(semaphores[unlock_sem],LONG_MAX); +              detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX); +              boost::throw_exception(thread_resource_error()); +            }              state_data state_={0};              state=state_;          } @@ -106,7 +120,7 @@ namespace boost                          return false;                      }                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  { @@ -165,7 +179,7 @@ namespace boost                  {                      return true;                  } -                     +                  unsigned long const res=detail::win32::WaitForSingleObject(semaphores[unlock_sem],::boost::detail::get_milliseconds_until(wait_until));                  if(res==detail::win32::timeout)                  { @@ -202,11 +216,120 @@ namespace boost                      }                      return false;                  } -                 +                  BOOST_ASSERT(res==0);              }          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_shared_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_shared_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_lock_shared_until(s_now + ceil<system_clock::duration>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; +          return try_lock_shared_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); +        } +        bool try_lock_shared_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) +        { +          for(;;) +          { +            state_data old_state=state; +            for(;;) +            { +              state_data new_state=old_state; +              if(new_state.exclusive || new_state.exclusive_waiting_blocked) +              { +                  ++new_state.shared_waiting; +                  if(!new_state.shared_waiting) +                  { +                      boost::throw_exception(boost::lock_error()); +                  } +              } +              else +              { +                  ++new_state.shared_count; +                  if(!new_state.shared_count) +                  { +                      boost::throw_exception(boost::lock_error()); +                  } +              } + +              state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); +              if(current_state==old_state) +              { +                  break; +              } +              old_state=current_state; +            } + +            if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) +            { +              return true; +            } + +            chrono::system_clock::time_point n = chrono::system_clock::now(); +            unsigned long res; +            if (tp>n) { +              chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-n); +              res=detail::win32::WaitForSingleObject(semaphores[unlock_sem], +                static_cast<unsigned long>(rel_time.count())); +            } else { +              res=detail::win32::timeout; +            } +            if(res==detail::win32::timeout) +            { +              for(;;) +              { +                state_data new_state=old_state; +                if(new_state.exclusive || new_state.exclusive_waiting_blocked) +                { +                  if(new_state.shared_waiting) +                  { +                      --new_state.shared_waiting; +                  } +                } +                else +                { +                  ++new_state.shared_count; +                  if(!new_state.shared_count) +                  { +                      return false; +                  } +                } + +                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); +                if(current_state==old_state) +                { +                    break; +                } +                old_state=current_state; +              } + +              if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) +              { +                return true; +              } +              return false; +            } + +            BOOST_ASSERT(res==0); +          } +        } +#endif +          void unlock_shared()          {              state_data old_state=state; @@ -214,7 +337,7 @@ namespace boost              {                  state_data new_state=old_state;                  bool const last_reader=!--new_state.shared_count; -                 +                  if(last_reader)                  {                      if(new_state.upgrade) @@ -232,7 +355,7 @@ namespace boost                          new_state.shared_waiting=0;                      }                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  { @@ -278,7 +401,7 @@ namespace boost                  {                      new_state.exclusive=true;                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  { @@ -306,7 +429,7 @@ namespace boost                          {                              boost::throw_exception(boost::lock_error());                          } -                         +                          new_state.exclusive_waiting_blocked=true;                      }                      else @@ -326,7 +449,12 @@ namespace boost                  {                      return true;                  } -                unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until)); +                #ifndef UNDER_CE +                const bool wait_all = true; +                #else +                const bool wait_all = false; +                #endif +                unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all,::boost::detail::get_milliseconds_until(wait_until));                  if(wait_res==detail::win32::timeout)                  {                      for(;;) @@ -364,6 +492,116 @@ namespace boost              }          } +#ifdef BOOST_THREAD_USES_CHRONO +        template <class Rep, class Period> +        bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) +        { +          return try_lock_until(chrono::steady_clock::now() + rel_time); +        } +        template <class Clock, class Duration> +        bool try_lock_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_lock_until(s_now + ceil<system_clock::duration>(t - c_now)); +        } +        template <class Duration> +        bool try_lock_until(const chrono::time_point<chrono::system_clock, Duration>& t) +        { +          using namespace chrono; +          typedef time_point<chrono::system_clock, chrono::system_clock::duration> sys_tmpt; +          return try_lock_until(sys_tmpt(chrono::ceil<chrono::system_clock::duration>(t.time_since_epoch()))); +        } +        bool try_lock_until(const chrono::time_point<chrono::system_clock, chrono::system_clock::duration>& tp) +        { +          for(;;) +          { +            state_data old_state=state; + +            for(;;) +            { +              state_data new_state=old_state; +              if(new_state.shared_count || new_state.exclusive) +              { +                ++new_state.exclusive_waiting; +                if(!new_state.exclusive_waiting) +                { +                    boost::throw_exception(boost::lock_error()); +                } + +                new_state.exclusive_waiting_blocked=true; +              } +              else +              { +                new_state.exclusive=true; +              } + +              state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); +              if(current_state==old_state) +              { +                break; +              } +              old_state=current_state; +            } + +            if(!old_state.shared_count && !old_state.exclusive) +            { +                return true; +            } +            #ifndef UNDER_CE +            const bool wait_all = true; +            #else +            const bool wait_all = false; +            #endif + +            chrono::system_clock::time_point n = chrono::system_clock::now(); +            unsigned long wait_res; +            if (tp>n) { +              chrono::milliseconds rel_time= chrono::ceil<chrono::milliseconds>(tp-chrono::system_clock::now()); +              wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,wait_all, +                  static_cast<unsigned long>(rel_time.count())); +            } else { +              wait_res=detail::win32::timeout; +            } +            if(wait_res==detail::win32::timeout) +            { +              for(;;) +              { +                state_data new_state=old_state; +                if(new_state.shared_count || new_state.exclusive) +                { +                  if(new_state.exclusive_waiting) +                  { +                    if(!--new_state.exclusive_waiting) +                    { +                      new_state.exclusive_waiting_blocked=false; +                    } +                  } +                } +                else +                { +                  new_state.exclusive=true; +                } + +                state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); +                if(current_state==old_state) +                { +                  break; +                } +                old_state=current_state; +              } +              if(!old_state.shared_count && !old_state.exclusive) +              { +                return true; +              } +              return false; +            } +            BOOST_ASSERT(wait_res<2); +          } +        } +#endif +          void unlock()          {              state_data old_state=state; @@ -426,7 +664,7 @@ namespace boost                  {                      return;                  } -                     +                  BOOST_VERIFY(!detail::win32::WaitForSingleObject(semaphores[unlock_sem],detail::win32::infinite));              }          } @@ -450,7 +688,7 @@ namespace boost                      }                      new_state.upgrade=true;                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  { @@ -469,7 +707,7 @@ namespace boost                  state_data new_state=old_state;                  new_state.upgrade=false;                  bool const last_reader=!--new_state.shared_count; -                 +                  if(last_reader)                  {                      if(new_state.exclusive_waiting) @@ -479,13 +717,15 @@ namespace boost                      }                      new_state.shared_waiting=0;                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  {                      if(last_reader)                      {                          release_waiters(old_state); +                    } else { +                        release_waiters(old_state);                      }                      break;                  } @@ -500,13 +740,13 @@ namespace boost              {                  state_data new_state=old_state;                  bool const last_reader=!--new_state.shared_count; -                 +                  if(last_reader)                  {                      new_state.upgrade=false;                      new_state.exclusive=true;                  } -                 +                  state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);                  if(current_state==old_state)                  { @@ -545,7 +785,28 @@ namespace boost              }              release_waiters(old_state);          } -         +//        bool try_unlock_upgrade_and_lock() +//        { +//          return false; +//        } +//#ifdef BOOST_THREAD_USES_CHRONO +//        template <class Rep, class Period> +//        bool +//        try_unlock_upgrade_and_lock_for( +//                                const chrono::duration<Rep, Period>& rel_time) +//        { +//          return try_unlock_upgrade_and_lock_until( +//                                 chrono::steady_clock::now() + rel_time); +//        } +//        template <class Clock, class Duration> +//        bool +//        try_unlock_upgrade_and_lock_until( +//                          const chrono::time_point<Clock, Duration>& abs_time) +//        { +//          return false; +//        } +//#endif +          void unlock_and_lock_shared()          {              state_data old_state=state; @@ -570,7 +831,6 @@ namespace boost              }              release_waiters(old_state);          } -                  void unlock_upgrade_and_lock_shared()          {              state_data old_state=state; @@ -594,8 +854,10 @@ namespace boost              }              release_waiters(old_state);          } -         +      }; +    typedef shared_mutex upgrade_mutex; +  }  #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp index c86b0fa..18fd7cb 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp @@ -4,51 +4,116 @@  // accompanying file LICENSE_1_0.txt or copy at  // http://www.boost.org/LICENSE_1_0.txt)  // (C) Copyright 2008 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba  #include <boost/thread/detail/config.hpp> -#include <boost/intrusive_ptr.hpp>  #include <boost/thread/thread_time.hpp> -#include "thread_primitives.hpp" -#include "thread_heap_alloc.hpp" +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/thread_heap_alloc.hpp> + +#include <boost/intrusive_ptr.hpp> +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif + +#include <map> +#include <vector> +#include <utility>  #include <boost/config/abi_prefix.hpp>  namespace boost  { +  class condition_variable; +  class mutex; + +  class thread_attributes { +  public: +      thread_attributes() BOOST_NOEXCEPT { +        val_.stack_size = 0; +        //val_.lpThreadAttributes=0; +      } +      ~thread_attributes() { +      } +      // stack size +      void set_stack_size(std::size_t size) BOOST_NOEXCEPT { +        val_.stack_size = size; +      } + +      std::size_t get_stack_size() const BOOST_NOEXCEPT { +          return val_.stack_size; +      } + +      //void set_security(LPSECURITY_ATTRIBUTES lpThreadAttributes) +      //{ +      //  val_.lpThreadAttributes=lpThreadAttributes; +      //} +      //LPSECURITY_ATTRIBUTES get_security() +      //{ +      //  return val_.lpThreadAttributes; +      //} + +      struct win_attrs { +        std::size_t stack_size; +        //LPSECURITY_ATTRIBUTES lpThreadAttributes; +      }; +      typedef win_attrs native_handle_type; +      native_handle_type* native_handle() {return &val_;} +      const native_handle_type* native_handle() const {return &val_;} + +  private: +      win_attrs val_; +  }; +      namespace detail      { +        struct tss_cleanup_function;          struct thread_exit_callback_node; -        struct tss_data_node; +        struct tss_data_node +        { +            boost::shared_ptr<boost::detail::tss_cleanup_function> func; +            void* value; + +            tss_data_node(boost::shared_ptr<boost::detail::tss_cleanup_function> func_, +                          void* value_): +                func(func_),value(value_) +            {} +        };          struct thread_data_base;          void intrusive_ptr_add_ref(thread_data_base * p);          void intrusive_ptr_release(thread_data_base * p); -         -        struct thread_data_base + +        struct BOOST_THREAD_DECL thread_data_base          {              long count;              detail::win32::handle_manager thread_handle;              detail::win32::handle_manager interruption_handle;              boost::detail::thread_exit_callback_node* thread_exit_callbacks; -            boost::detail::tss_data_node* tss_data; +            std::map<void const*,boost::detail::tss_data_node> tss_data;              bool interruption_enabled;              unsigned id; +            typedef std::vector<std::pair<condition_variable*, mutex*> +            //, hidden_allocator<std::pair<condition_variable*, mutex*> > +            > notify_list_t; +            notify_list_t notify; +              thread_data_base():                  count(0),thread_handle(detail::win32::invalid_handle_value),                  interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)), -                thread_exit_callbacks(0),tss_data(0), +                thread_exit_callbacks(0),tss_data(),                  interruption_enabled(true), -                id(0) -            {} -            virtual ~thread_data_base() +                id(0), +                notify()              {} +            virtual ~thread_data_base();              friend void intrusive_ptr_add_ref(thread_data_base * p)              {                  BOOST_INTERLOCKED_INCREMENT(&p->count);              } -             +              friend void intrusive_ptr_release(thread_data_base * p)              {                  if(!BOOST_INTERLOCKED_DECREMENT(&p->count)) @@ -61,15 +126,21 @@ namespace boost              {                  BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0);              } -             +              typedef detail::win32::handle native_handle_type;              virtual void run()=0; + +            void notify_all_at_thread_exit(condition_variable* cv, mutex* m) +            { +              notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); +            } +          };          typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr; -        struct timeout +        struct BOOST_SYMBOL_VISIBLE timeout          {              unsigned long start;              uintmax_t milliseconds; @@ -92,7 +163,7 @@ namespace boost                  abs_time(abs_time_)              {} -            struct remaining_time +            struct BOOST_SYMBOL_VISIBLE remaining_time              {                  bool more;                  unsigned long milliseconds; @@ -130,7 +201,7 @@ namespace boost              {                  return milliseconds==~uintmax_t(0);              } -             +              static timeout sentinel()              { @@ -139,43 +210,49 @@ namespace boost          private:              struct sentinel_type              {}; -                 +              explicit timeout(sentinel_type):                  start(0),milliseconds(~uintmax_t(0)),relative(true)              {}          }; -        inline unsigned long pin_to_zero(long value) +        inline uintmax_t pin_to_zero(intmax_t value)          { -            return (value<0)?0u:(unsigned long)value; +            return (value<0)?0u:(uintmax_t)value;          }      }      namespace this_thread      { -        void BOOST_THREAD_DECL yield(); +        void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT;          bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time); -        inline void interruptible_wait(unsigned long milliseconds) +        inline void interruptible_wait(uintmax_t milliseconds)          {              interruptible_wait(detail::win32::invalid_handle_value,milliseconds);          } -        inline void interruptible_wait(system_time const& abs_time) +        inline BOOST_SYMBOL_VISIBLE void interruptible_wait(system_time const& abs_time)          {              interruptible_wait(detail::win32::invalid_handle_value,abs_time);          }          template<typename TimeDuration> -        inline void sleep(TimeDuration const& rel_time) +        inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)          {              interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));          } -        inline void sleep(system_time const& abs_time) +        inline BOOST_SYMBOL_VISIBLE void sleep(system_time const& abs_time)          {              interruptible_wait(abs_time);          } +#ifdef BOOST_THREAD_USES_CHRONO +        inline void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) +        { +          interruptible_wait(chrono::duration_cast<chrono::milliseconds>(ns).count()); +        } +#endif      } -     +  }  #include <boost/config/abi_suffix.hpp> diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp index c210a91..9b6d390 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp @@ -5,7 +5,7 @@  #ifndef THREAD_HEAP_ALLOC_HPP  #define THREAD_HEAP_ALLOC_HPP  #include <new> -#include "thread_primitives.hpp" +#include <boost/thread/win32/thread_primitives.hpp>  #include <stdexcept>  #include <boost/assert.hpp>  #include <boost/throw_exception.hpp> @@ -56,7 +56,7 @@ namespace boost  {      namespace detail      { -        inline /*BOOST_THREAD_DECL*/ void* allocate_raw_heap_memory(unsigned size) +        inline void* allocate_raw_heap_memory(unsigned size)          {              void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size);              if(!heap_memory) @@ -66,153 +66,189 @@ namespace boost              return heap_memory;          } -        inline /*BOOST_THREAD_DECL*/ void free_raw_heap_memory(void* heap_memory) +        inline void free_raw_heap_memory(void* heap_memory)          {              BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0);          } -             +          template<typename T>          inline T* heap_new()          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T();                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          } -#ifndef BOOST_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES          template<typename T,typename A1>          inline T* heap_new(A1&& a1)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(static_cast<A1&&>(a1));                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2>          inline T* heap_new(A1&& a1,A2&& a2)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2));                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2,typename A3>          inline T* heap_new(A1&& a1,A2&& a2,A3&& a3)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),                                                    static_cast<A3&&>(a3));                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2,typename A3,typename A4>          inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2),                                                    static_cast<A3&&>(a3),static_cast<A4&&>(a4));                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }  #else          template<typename T,typename A1>          inline T* heap_new_impl(A1 a1)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(a1);                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2>          inline T* heap_new_impl(A1 a1,A2 a2)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(a1,a2);                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2,typename A3>          inline T* heap_new_impl(A1 a1,A2 a2,A3 a3)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(a1,a2,a3);                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          }          template<typename T,typename A1,typename A2,typename A3,typename A4>          inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4)          {              void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); -            try +#ifndef BOOST_NO_EXCEPTIONS +            try // BOOST_NO_EXCEPTIONS protected +#endif              {                  T* const data=new (heap_memory) T(a1,a2,a3,a4);                  return data;              } -            catch(...) +#ifndef BOOST_NO_EXCEPTIONS +            catch(...) // BOOST_NO_EXCEPTIONS protected              {                  free_raw_heap_memory(heap_memory); -                throw; +                throw; // BOOST_NO_EXCEPTIONS protected              } +#endif          } @@ -226,7 +262,7 @@ namespace boost          {              return heap_new_impl<T,A1&>(a1);          } -         +          template<typename T,typename A1,typename A2>          inline T* heap_new(A1 const& a1,A2 const& a2)          { @@ -372,8 +408,8 @@ namespace boost          {              return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4);          } -         -#endif         + +#endif          template<typename T>          inline void heap_delete(T* data)          { diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp index 9b20e86..c0dba11 100644 --- a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -3,14 +3,14 @@  //  win32_thread_primitives.hpp  // -//  (C) Copyright 2005-7 Anthony Williams  -//  (C) Copyright 2007 David Deakins  +//  (C) Copyright 2005-7 Anthony Williams +//  (C) Copyright 2007 David Deakins  //  //  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) -#include <boost/config.hpp> +#include <boost/thread/detail/config.hpp>  #include <boost/throw_exception.hpp>  #include <boost/assert.hpp>  #include <boost/thread/exceptions.hpp> @@ -94,7 +94,7 @@ namespace boost      {          namespace win32          { -             +  # ifdef _WIN64              typedef unsigned __int64 ulong_ptr;  # else @@ -170,20 +170,20 @@ namespace boost                  auto_reset_event=false,                  manual_reset_event=true              }; -             +              enum initial_event_state              {                  event_initially_reset=false,                  event_initially_set=true              }; -             +              inline handle create_anonymous_event(event_type type,initial_event_state state)              { -#if !defined(BOOST_NO_ANSI_APIS)   +#if !defined(BOOST_NO_ANSI_APIS)                  handle const res=win32::CreateEventA(0,type,state,0);  #else                  handle const res=win32::CreateEventW(0,type,state,0); -#endif                 +#endif                  if(!res)                  {                      boost::throw_exception(thread_resource_error()); @@ -193,17 +193,26 @@ namespace boost              inline handle create_anonymous_semaphore(long initial_count,long max_count)              { -#if !defined(BOOST_NO_ANSI_APIS)   +#if !defined(BOOST_NO_ANSI_APIS)                  handle const res=CreateSemaphoreA(0,initial_count,max_count,0);  #else                  handle const res=CreateSemaphoreW(0,initial_count,max_count,0); -#endif                +#endif                  if(!res)                  {                      boost::throw_exception(thread_resource_error());                  }                  return res;              } +            inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count) +            { +#if !defined(BOOST_NO_ANSI_APIS) +                handle const res=CreateSemaphoreA(0,initial_count,max_count,0); +#else +                handle const res=CreateSemaphoreW(0,initial_count,max_count,0); +#endif +                return res; +            }              inline handle duplicate_handle(handle source)              { @@ -237,7 +246,7 @@ namespace boost                          BOOST_VERIFY(CloseHandle(handle_to_manage));                      }                  } -                 +              public:                  explicit handle_manager(handle handle_to_manage_):                      handle_to_manage(handle_to_manage_) @@ -245,7 +254,7 @@ namespace boost                  handle_manager():                      handle_to_manage(0)                  {} -                 +                  handle_manager& operator=(handle new_handle)                  {                      cleanup(); @@ -279,13 +288,13 @@ namespace boost                  {                      return !handle_to_manage;                  } -                 +                  ~handle_manager()                  {                      cleanup();                  }              }; -             +          }      }  } @@ -318,7 +327,7 @@ namespace boost              {                  return _interlockedbittestandreset(x,bit)!=0;              } -             +          }      }  } @@ -332,24 +341,50 @@ namespace boost          {              inline bool interlocked_bit_test_and_set(long* x,long bit)              { +#ifndef BOOST_INTEL_CXX_VERSION                  __asm {                      mov eax,bit;                      mov edx,x;                      lock bts [edx],eax;                      setc al; -                };           +                }; +#else +                bool ret; +                __asm { +                    mov eax,bit +                    mov edx,x +                    lock bts [edx],eax +                    setc al +                    mov ret, al +                }; +                return ret; + +#endif              }              inline bool interlocked_bit_test_and_reset(long* x,long bit)              { +#ifndef BOOST_INTEL_CXX_VERSION                  __asm {                      mov eax,bit;                      mov edx,x;                      lock btr [edx],eax;                      setc al; -                };           +                }; +#else +                bool ret; +                __asm { +                    mov eax,bit +                    mov edx,x +                    lock btr [edx],eax +                    setc al +                    mov ret, al +                }; +                return ret; + +#endif              } -             +          }      }  } diff --git a/3rdParty/Boost/src/boost/thread/xtime.hpp b/3rdParty/Boost/src/boost/thread/xtime.hpp index 7cc6272..1ca996f 100644 --- a/3rdParty/Boost/src/boost/thread/xtime.hpp +++ b/3rdParty/Boost/src/boost/thread/xtime.hpp @@ -2,7 +2,7 @@  // William E. Kempf  // Copyright (C) 2007-8 Anthony Williams  // -//  Distributed under the Boost Software License, Version 1.0. (See accompanying  +//  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_XTIME_WEK070601_HPP @@ -20,7 +20,7 @@ namespace boost {  enum xtime_clock_types  { -    TIME_UTC=1 +    TIME_UTC_=1  //    TIME_TAI,  //    TIME_MONOTONIC,  //    TIME_PROCESS, @@ -53,14 +53,14 @@ struct xtime          boost::posix_time::microseconds((nsec+500)/1000);  #endif      } -     +  };  inline xtime get_xtime(boost::system_time const& abs_time)  {      xtime res;      boost::posix_time::time_duration const time_since_epoch=abs_time-boost::posix_time::from_time_t(0); -             +      res.sec=static_cast<xtime::xtime_sec_t>(time_since_epoch.total_seconds());      res.nsec=static_cast<xtime::xtime_nsec_t>(time_since_epoch.fractional_seconds()*(1000000000/time_since_epoch.ticks_per_second()));      return res; @@ -68,7 +68,7 @@ inline xtime get_xtime(boost::system_time const& abs_time)  inline int xtime_get(struct xtime* xtp, int clock_type)  { -    if (clock_type == TIME_UTC) +    if (clock_type == TIME_UTC_)      {          *xtp=get_xtime(get_system_time());          return clock_type; @@ -81,7 +81,7 @@ inline int xtime_cmp(const xtime& xt1, const xtime& xt2)  {      if (xt1.sec == xt2.sec)          return (int)(xt1.nsec - xt2.nsec); -    else  +    else          return (xt1.sec > xt2.sec) ? 1 : -1;  } | 
 Swift
 Swift