Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r83525 - in branches/release: boost/thread boost/thread/detail boost/thread/pthread boost/thread/v2 boost/thread/win32 libs/thread libs/thread/build libs/thread/doc libs/thread/example libs/thread/src libs/thread/src/pthread libs/thread/src/win32 libs/thread/test libs/thread/test/sync/futures/packaged_task libs/thread/test/sync/futures/promise libs/thread/test/sync/mutual_exclusion/once/call_once libs/thread/test/sync/mutual_exclusion/synchronized_value
From: vicente.botet_at_[hidden]
Date: 2013-03-22 21:48:44


Author: viboes
Date: 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
New Revision: 83525
URL: http://svn.boost.org/trac/boost/changeset/83525

Log:
Thread: merge from trunk. 1.54
Added:
   branches/release/libs/thread/doc/lockable_adapter.qbk
      - copied unchanged from r83508, /trunk/libs/thread/doc/lockable_adapter.qbk
   branches/release/libs/thread/doc/synchronized_value.qbk
      - copied unchanged from r83508, /trunk/libs/thread/doc/synchronized_value.qbk
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/indirect_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/swap_pass.cpp
   branches/release/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp
   branches/release/libs/thread/test/test_7720.cpp
      - copied unchanged from r82959, /trunk/libs/thread/test/test_7720.cpp
   branches/release/libs/thread/test/test_7755.cpp
      - copied unchanged from r83508, /trunk/libs/thread/test/test_7755.cpp
Properties modified:
   branches/release/boost/thread/ (props changed)
   branches/release/libs/thread/ (props changed)
Text files modified:
   branches/release/boost/thread/detail/config.hpp | 49 ++
   branches/release/boost/thread/detail/invoke.hpp | 171 ++++++++++
   branches/release/boost/thread/future.hpp | 75 +++-
   branches/release/boost/thread/is_locked_by_this_thread.hpp | 2
   branches/release/boost/thread/lock_concepts.hpp | 2
   branches/release/boost/thread/pthread/once.hpp | 103 ++----
   branches/release/boost/thread/pthread/once_atomic.hpp | 138 ++++----
   branches/release/boost/thread/shared_mutex.hpp | 1
   branches/release/boost/thread/synchronized_value.hpp | 604 ++++++++++++++++++++++++++++++++++++---
   branches/release/boost/thread/testable_mutex.hpp | 68 ++--
   branches/release/boost/thread/v2/thread.hpp | 7
   branches/release/boost/thread/win32/basic_timed_mutex.hpp | 5
   branches/release/boost/thread/win32/once.hpp | 377 +++++++++++++++++++-----
   branches/release/boost/thread/win32/shared_mutex.hpp | 21 +
   branches/release/boost/thread/win32/thread_data.hpp | 10
   branches/release/boost/thread/win32/thread_primitives.hpp | 30 +
   branches/release/libs/thread/build/Jamfile.v2 | 29 +
   branches/release/libs/thread/doc/barrier.qbk | 5
   branches/release/libs/thread/doc/changes.qbk | 25 +
   branches/release/libs/thread/doc/compliance.qbk | 10
   branches/release/libs/thread/doc/configuration.qbk | 12
   branches/release/libs/thread/doc/internal_locking.qbk | 29 +
   branches/release/libs/thread/doc/mutex_concepts.qbk | 235 +++++++++++++++
   branches/release/libs/thread/doc/mutexes.qbk | 407 ++++++++++++++++++++++++++
   branches/release/libs/thread/doc/once.qbk | 20
   branches/release/libs/thread/doc/sync_tutorial.qbk | 2
   branches/release/libs/thread/doc/thread.qbk | 1
   branches/release/libs/thread/doc/thread_ref.qbk | 3
   branches/release/libs/thread/example/make_future.cpp | 19 +
   branches/release/libs/thread/example/synchronized_person.cpp | 23 +
   branches/release/libs/thread/example/synchronized_value.cpp | 76 ++++
   branches/release/libs/thread/src/future.cpp | 4
   branches/release/libs/thread/src/pthread/once_atomic.cpp | 31 -
   branches/release/libs/thread/src/win32/thread.cpp | 8
   branches/release/libs/thread/test/Jamfile.v2 | 44 ++
   branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp | 12
   branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp | 61 +--
   branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp | 12
   branches/release/libs/thread/test/test_barrier.cpp | 24
   39 files changed, 2246 insertions(+), 509 deletions(-)

Modified: branches/release/boost/thread/detail/config.hpp
==============================================================================
--- branches/release/boost/thread/detail/config.hpp (original)
+++ branches/release/boost/thread/detail/config.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -1,6 +1,6 @@
 // Copyright (C) 2001-2003
 // William E. Kempf
-// Copyright (C) 2011-2012 Vicente J. Botet Escriba
+// Copyright (C) 2011-2013 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)
@@ -8,15 +8,27 @@
 #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>
 #include <boost/thread/detail/platform.hpp>
 
+//#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+
+
+// ATTRIBUTE_MAY_ALIAS
+
+#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) > 302 \
+ && !defined(__INTEL_COMPILER)
+
+ // GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
+ // regard to violation of the strict aliasing rules.
+
+ #define BOOST_THREAD_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
+ #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
+#else
+ #define BOOST_THREAD_ATTRIBUTE_MAY_ALIAS
+#endif
+
 #if ! defined BOOST_THREAD_NOEXCEPT_OR_THROW
 #ifdef BOOST_NO_CXX11_NOEXCEPT
 # define BOOST_THREAD_NOEXCEPT_OR_THROW throw()
@@ -44,8 +56,8 @@
 #if defined __IBMCPP__ && (__IBMCPP__ < 1100) \
   && ! defined BOOST_THREAD_DONT_USE_CHRONO
 #define BOOST_THREAD_DONT_USE_CHRONO
-#if ! defined BOOST_THREAD_USE_DATE
-#define BOOST_THREAD_USE_DATE
+#if ! defined BOOST_THREAD_USES_DATETIME
+#define BOOST_THREAD_USES_DATETIME
 #endif
 #endif
 
@@ -76,13 +88,14 @@
 
 #if defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
 #define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
+#define BOOST_THREAD_NO_SYNCHRONIZE
 #elif defined _MSC_VER && _MSC_VER <= 1600
 // C++ features supported by VC++ 10 (aka 2010)
 #define BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS
+#define BOOST_THREAD_NO_SYNCHRONIZE
 #endif
 
 /// BASIC_THREAD_ID
-// todo to be removed for 1.54
 #if ! defined BOOST_THREAD_DONT_PROVIDE_BASIC_THREAD_ID \
  && ! defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
 #define BOOST_THREAD_PROVIDES_BASIC_THREAD_ID
@@ -111,9 +124,7 @@
 
 #if ! defined BOOST_THREAD_DONT_USE_ATOMIC \
   && ! defined BOOST_THREAD_USES_ATOMIC
-//#if ! defined __PGIC__
 #define BOOST_THREAD_USES_ATOMIC
-//#endif
 //#define BOOST_THREAD_DONT_USE_ATOMIC
 #endif
 
@@ -246,6 +257,16 @@
 #endif
 #endif
 
+
+// MAKE_READY_AT_THREAD_EXIT
+#if ! defined BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT \
+ && ! defined BOOST_THREAD_DONT_PROVIDE_MAKE_READY_AT_THREAD_EXIT
+
+//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+#define BOOST_THREAD_PROVIDES_MAKE_READY_AT_THREAD_EXIT
+//#endif
+#endif
+
 // FUTURE_CONTINUATION
 #if ! defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION \
  && ! defined BOOST_THREAD_DONT_PROVIDE_FUTURE_CONTINUATION
@@ -301,8 +322,12 @@
 #endif
 #endif
 
+#if defined(BOOST_THREAD_PLATFORM_WIN32) && defined BOOST_THREAD_DONT_USE_DATETIME
+#undef BOOST_THREAD_DONT_USE_DATETIME
+#define BOOST_THREAD_USES_DATETIME
+#endif
 
-// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.52
+// BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
 // BOOST_THREAD_DONT_PROVIDE_DEPRECATED_FEATURES_SINCE_V3_0_0 defined by default up to Boost 1.55
 #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
 

Modified: branches/release/boost/thread/detail/invoke.hpp
==============================================================================
--- branches/release/boost/thread/detail/invoke.hpp (original)
+++ branches/release/boost/thread/detail/invoke.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -18,6 +18,7 @@
 
 #include <boost/config.hpp>
 #include <boost/static_assert.hpp>
+#include <boost/thread/detail/move.hpp>
 #ifndef BOOST_NO_CXX11_HDR_FUNCTIONAL
 #include <functional>
 #endif
@@ -27,12 +28,12 @@
   namespace detail
   {
 
+#if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
 #if ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
     ! defined(BOOST_NO_CXX11_DECLTYPE) && \
     ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
- ! defined(BOOST_NO_CXX11_AUTO) && \
- ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ ! defined(BOOST_NO_CXX11_AUTO)
 
 #define BOOST_THREAD_PROVIDES_INVOKE
 
@@ -41,7 +42,7 @@
     template <class Fp, class A0, class ...Args>
     inline
     auto
- invoke(Fp&& f, A0&& a0, Args&& ...args)
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
         -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...))
     {
         return (boost::forward<A0>(a0).*f)(boost::forward<Args>(args)...);
@@ -50,7 +51,7 @@
     template <class Fp, class A0, class ...Args>
     inline
     auto
- invoke(Fp&& f, A0&& a0, Args&& ...args)
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(Args) ...args)
         -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...))
     {
         return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(args)...);
@@ -61,7 +62,7 @@
     template <class Fp, class A0>
     inline
     auto
- invoke(Fp&& f, A0&& a0)
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
         -> decltype(boost::forward<A0>(a0).*f)
     {
         return boost::forward<A0>(a0).*f;
@@ -70,7 +71,7 @@
     template <class Fp, class A0>
     inline
     auto
- invoke(Fp&& f, A0&& a0)
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
         -> decltype((*boost::forward<A0>(a0)).*f)
     {
         return (*boost::forward<A0>(a0)).*f;
@@ -80,20 +81,17 @@
 
     template <class Fp, class ...Args>
     inline
- auto invoke(Fp&& f, Args&& ...args)
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
     -> decltype(boost::forward<Fp>(f)(boost::forward<Args>(args)...))
     {
       return boost::forward<Fp>(f)(boost::forward<Args>(args)...);
     }
-#else
-#if ! defined(BOOST_NO_SFINAE_EXPR) && \
- ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
- ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL && \
- ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#elif ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL
 
     template <class Ret, class Fp, class ...Args>
     inline
- Ret invoke(Fp&& f, Args&& ...args)
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) ...args)
     {
       return std::bind(boost::forward<Fp>(f), boost::forward<Args>(args)...)();
     }
@@ -102,7 +100,152 @@
 
 #endif
 
+#else //! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+
+#if ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE) && \
+ ! defined(BOOST_NO_CXX11_DECLTYPE_N3276) && \
+ ! defined(BOOST_NO_CXX11_AUTO)
+
+#define BOOST_THREAD_PROVIDES_INVOKE
+
+ // // bullets 1 and 2
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((boost::forward<A0>(a0).*f)())
+ {
+ return (boost::forward<A0>(a0).*f)();
+ }
+ template <class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(a1)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(a1));
+ }
+ template <class Fp, class A0, class A1, class A2>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype((boost::forward<A0>(a0).*f)(boost::forward<Args>(a1), boost::forward<Args>(a2)))
+ {
+ return (boost::forward<A0>(a0).*f)(boost::forward<Args>(a1), boost::forward<Args>(a2));
+ }
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(((*boost::forward<A0>(a0)).*f)())
+ {
+ return ((*boost::forward<A0>(a0)).*f)();
+ }
+ template <class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(a1)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(a1));
+ }
+ template <class Fp, class A0, class A1>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(a1), boost::forward<Args>(a2)))
+ {
+ return ((*boost::forward<A0>(a0)).*f)(boost::forward<Args>(a1), boost::forward<Args>(a2));
+ }
+
+ // bullets 3 and 4
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype(boost::forward<A0>(a0).*f)
+ {
+ return boost::forward<A0>(a0).*f;
+ }
+
+ template <class Fp, class A0>
+ inline
+ auto
+ invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A0) a0)
+ -> decltype((*boost::forward<A0>(a0)).*f)
+ {
+ return (*boost::forward<A0>(a0)).*f;
+ }
+
+ // bullet 5
+
+ template <class Fp>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f)
+ -> decltype(boost::forward<Fp>(f)())
+ {
+ return boost::forward<Fp>(f)();
+ }
+ template <class Fp, class A1>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(Args) a1)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1));
+ } template <class Fp, class A1, class A2>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2));
+ }
+ template <class Fp, class A1, class A2, class A3>
+ inline
+ auto invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ -> decltype(boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3)))
+ {
+ return boost::forward<Fp>(f)(boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3));
+ }
+
+
+#elif ! defined(BOOST_NO_SFINAE_EXPR) && \
+ ! defined BOOST_NO_CXX11_HDR_FUNCTIONAL
+
+ template <class Ret, class Fp>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f)
+ {
+ return f();
+ }
+ template <class Ret, class Fp, class A1>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1))();
+ }
+ template <class Ret, class Fp, class A1, class A2>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2))();
+ }
+ template <class Ret, class Fp, class A1, class A2, class A3>
+ inline
+ Ret invoke(BOOST_THREAD_RV_REF(Fp) f, BOOST_THREAD_RV_REF(A1) a1, BOOST_THREAD_RV_REF(A2) a2, BOOST_THREAD_RV_REF(A3) a3)
+ {
+ return std::bind(boost::forward<Fp>(f), boost::forward<A1>(a1), boost::forward<A2>(a2), boost::forward<A3>(a3))();
+ }
+
+#define BOOST_THREAD_PROVIDES_INVOKE_RET
+
 #endif
+
+
+#endif // ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
       }
     }
 

Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp (original)
+++ branches/release/boost/thread/future.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -1677,7 +1677,11 @@
                 boost::throw_exception(future_already_retrieved());
             }
             future_obtained=true;
- return BOOST_THREAD_FUTURE<R>(future_);
+ return
+ //BOOST_THREAD_MAKE_RV_REF(
+ BOOST_THREAD_FUTURE<R>(future_)
+ //)
+ ;
         }
 
         void set_value(typename detail::future_traits<R>::source_reference_type r)
@@ -1845,6 +1849,7 @@
             }
             future_obtained=true;
             return BOOST_THREAD_FUTURE<R&>(future_);
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R&>(future_));
         }
 
         void set_value(R& r)
@@ -1990,6 +1995,9 @@
             }
             future_obtained=true;
             return BOOST_THREAD_FUTURE<void>(future_);
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<void>(future_));
+ //BOOST_THREAD_FUTURE<void> res;
+ //return boost::move(res);
         }
 
         void set_value()
@@ -2938,8 +2946,8 @@
             else if(!future_obtained)
             {
                 future_obtained=true;
- //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R>(task));
                 return BOOST_THREAD_FUTURE<R>(task);
+ //return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<R>(task));
             }
             else
             {
@@ -3139,12 +3147,12 @@
         if (int(policy) & int(launch::async))
         {
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- return boost::detail::make_future_async_object<Rp>(
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_async_object<Rp>(
               BF(
                   thread_detail::decay_copy(boost::forward<F>(f))
                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
               )
- );
+ ));
 #else
           packaged_task_type pt( boost::forward<F>(f) );
 
@@ -3160,12 +3168,12 @@
         else if (int(policy) & int(launch::deferred))
         {
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- return boost::detail::make_future_deferred_object<Rp>(
+ return BOOST_THREAD_MAKE_RV_REF(boost::detail::make_future_deferred_object<Rp>(
               BF(
                   thread_detail::decay_copy(boost::forward<F>(f))
                   , thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
               )
- );
+ ));
 #else
               BOOST_THREAD_FUTURE<R> ret;
               return ::boost::move(ret);
@@ -3194,14 +3202,14 @@
         BOOST_THREAD_FUTURE<R>
         async(R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
         {
- return async(launch(launch::any), f, boost::forward<ArgTypes>(args)...);
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f, boost::forward<ArgTypes>(args)...));
         }
 #else
         template <class R>
         BOOST_THREAD_FUTURE<R>
         async(R(*f)())
         {
- return async(launch(launch::any), f);
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
         }
 #endif
 #endif
@@ -3213,14 +3221,14 @@
         )>::type>
         async(BOOST_THREAD_FWD_REF(F) f, BOOST_THREAD_FWD_REF(ArgTypes)... args)
         {
- return async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...);
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f), boost::forward<ArgTypes>(args)...));
         }
 #else
         template <class F>
         BOOST_THREAD_FUTURE<typename boost::result_of<F()>::type>
         async(BOOST_THREAD_RV_REF(F) f)
         {
- return async(launch(launch::any), boost::forward<F>(f));
+ return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), boost::forward<F>(f)));
         }
 #endif
 
@@ -3234,16 +3242,17 @@
     typedef typename decay<T>::type future_type;
     promise<future_type> p;
     p.set_value(boost::forward<T>(value));
- return p.get_future();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
   }
 
-
+#if defined BOOST_THREAD_USES_MOVE
   inline BOOST_THREAD_FUTURE<void> make_future()
   {
     promise<void> p;
- return p.get_future();
-
+ p.set_value();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future());
   }
+#endif
 
   ////////////////////////////////
   // make_shared_future
@@ -3254,14 +3263,14 @@
     typedef typename decay<T>::type future_type;
     promise<future_type> p;
     p.set_value(boost::forward<T>(value));
- return p.get_future().share();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
   }
 
 
   inline shared_future<void> make_shared_future()
   {
     promise<void> p;
- return p.get_future().share();
+ return BOOST_THREAD_MAKE_RV_REF(p.get_future().share());
 
   }
 
@@ -3397,10 +3406,10 @@
           new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func), policy);
       if (ptr==0)
       {
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
       }
       this->future_->set_continuation_ptr(ptr, lock);
- return ptr->next.get_future();
+ return BOOST_THREAD_MAKE_RV_REF(ptr->next.get_future());
     }
     else
     {
@@ -3421,16 +3430,20 @@
     {
       boost::unique_lock<boost::mutex> lock(this->future_->mutex);
       detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F > *ptr =
- new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func));
+ new
+ //BOOST_THREAD_MAKE_RV_REF((
+ detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, F>(*this, boost::forward<F>(func))
+ //))
+ ;
       if (ptr==0)
       {
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
       }
       this->future_->set_continuation_ptr(ptr, lock);
       return ptr->next.get_future();
     } else {
       // fixme what to do when the future has no associated state?
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
     }
 
   }
@@ -3447,16 +3460,20 @@
     {
       boost::unique_lock<boost::mutex> lock(this->future_->mutex);
       detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
- new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func);
+ new
+ //BOOST_THREAD_MAKE_RV_REF((
+ detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func)
+ // ))
+ ;
       if (ptr==0)
       {
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
       }
       this->future_->set_continuation_ptr(ptr, lock);
       return ptr->next.get_future();
     } else {
       // fixme what to do when the future has no associated state?
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
     }
 
   }
@@ -3472,16 +3489,20 @@
     {
       boost::unique_lock<boost::mutex> lock(this->future_->mutex);
       detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&) > *ptr =
- new detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy);
+ new
+ //BOOST_THREAD_MAKE_RV_REF((
+ detail::future_continuation<BOOST_THREAD_FUTURE<R>, future_type, RF(*)(BOOST_THREAD_FUTURE&)>(*this, func, policy)
+ // ))
+ ;
       if (ptr==0)
       {
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
       }
       this->future_->set_continuation_ptr(ptr, lock);
       return ptr->next.get_future();
     } else {
       // fixme what to do when the future has no associated state?
- return BOOST_THREAD_FUTURE<future_type>();
+ return BOOST_THREAD_MAKE_RV_REF(BOOST_THREAD_FUTURE<future_type>());
     }
 
   }

Modified: branches/release/boost/thread/is_locked_by_this_thread.hpp
==============================================================================
--- branches/release/boost/thread/is_locked_by_this_thread.hpp (original)
+++ branches/release/boost/thread/is_locked_by_this_thread.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -25,7 +25,7 @@
   template <typename Lockable>
   bool is_locked_by_this_thread(testable_mutex<Lockable> const& mtx)
   {
- return mtx.is_locked();
+ return mtx.is_locked_by_this_thread();
   }
   template <typename Lockable>
   bool is_locked_by_this_thread(Lockable const&)

Modified: branches/release/boost/thread/lock_concepts.hpp
==============================================================================
--- branches/release/boost/thread/lock_concepts.hpp (original)
+++ branches/release/boost/thread/lock_concepts.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -30,7 +30,7 @@
   struct BasicLock
   {
     typedef typename Lk::mutex_type mutex_type;
- void cvt_mutex_ptr(mutex_type*);
+ void cvt_mutex_ptr(mutex_type*) {}
     BOOST_CONCEPT_ASSERT(( BasicLockable<mutex_type> ));
 
     BOOST_CONCEPT_USAGE(BasicLock)

Modified: branches/release/boost/thread/pthread/once.hpp
==============================================================================
--- branches/release/boost/thread/pthread/once.hpp (original)
+++ branches/release/boost/thread/pthread/once.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -94,6 +94,18 @@
 #define BOOST_ONCE_INIT {BOOST_ONCE_INITIAL_FLAG_VALUE}
 #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
 
+
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
     namespace thread_detail
     {
         BOOST_THREAD_DECL uintmax_atomic_t& get_once_per_thread_epoch();
@@ -129,28 +141,10 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
-#if defined BOOST_THREAD_PROVIDES_INVOKE
- detail::invoke(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
- detail::invoke<void>(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#else
- boost::bind(
+ BOOST_THREAD_INVOKE_RET_VOID(
                         thread_detail::decay_copy(boost::forward<Function>(f)),
                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- )();
-#endif
-#else
- f(
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#endif
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH (...)
                 {
@@ -239,11 +233,7 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1)();
-#else
- f(p1);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH (...)
                 {
@@ -286,11 +276,7 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2)();
-#else
- f(p1,p2);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
         }
                 BOOST_CATCH (...)
                 {
@@ -334,11 +320,7 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2,p3)();
-#else
- f(p1,p2,p3);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
         }
                 BOOST_CATCH (...)
                 {
@@ -426,16 +408,10 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH (...)
                 {
@@ -478,18 +454,11 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH (...)
                 {
@@ -533,20 +502,12 @@
                 BOOST_TRY
                 {
                     pthread::pthread_mutex_scoped_unlock relocker(&thread_detail::once_epoch_mutex);
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2)),
- thread_detail::decay_copy(boost::forward<T1>(p3))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2)),
- thread_detail::decay_copy(boost::forward<T1>(p3))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T1>(p2)),
+ thread_detail::decay_copy(boost::forward<T1>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH (...)
                 {

Modified: branches/release/boost/thread/pthread/once_atomic.hpp
==============================================================================
--- branches/release/boost/thread/pthread/once_atomic.hpp (original)
+++ branches/release/boost/thread/pthread/once_atomic.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -17,6 +17,7 @@
 #include <boost/thread/detail/invoke.hpp>
 #include <boost/detail/no_exceptions_support.hpp>
 #include <boost/bind.hpp>
+#include <boost/atomic.hpp>
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -27,9 +28,28 @@
 
   namespace thread_detail
   {
+
+#if BOOST_ATOMIC_INT_LOCK_FREE == 2
+ typedef unsigned int atomic_int_type;
+#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
+ typedef unsigned short atomic_int_type;
+#elif BOOST_ATOMIC_CHAR_LOCK_FREE == 2
+ typedef unsigned char atomic_int_type;
+#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
+ typedef unsigned long atomic_int_type;
+#elif defined(BOOST_HAS_LONG_LONG) && BOOST_ATOMIC_LLONG_LOCK_FREE == 2
+ typedef ulong_long_type atomic_int_type;
+#else
+ // All tested integer types are not atomic, the spinlock pool will be used
+ typedef unsigned int atomic_int_type;
+#endif
+
+ typedef boost::atomic<atomic_int_type> atomic_type;
+
     BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
     BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
     BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
   }
 
 #ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11
@@ -42,31 +62,59 @@
     }
 
   private:
- #if defined(__GNUC__)
- __attribute__((may_alias))
- #endif
- uintmax_t storage;
+ thread_detail::atomic_type storage;
 
     friend BOOST_THREAD_DECL bool thread_detail::enter_once_region(once_flag& flag) BOOST_NOEXCEPT;
     friend BOOST_THREAD_DECL void thread_detail::commit_once_region(once_flag& flag) BOOST_NOEXCEPT;
     friend BOOST_THREAD_DECL void thread_detail::rollback_once_region(once_flag& flag) BOOST_NOEXCEPT;
+ friend thread_detail::atomic_type& thread_detail::get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT;
   };
 
 #define BOOST_ONCE_INIT boost::once_flag()
 
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ //return reinterpret_cast< atomic_type& >(flag.storage);
+ return flag.storage;
+ }
+ }
+
 #else // BOOST_THREAD_PROVIDES_ONCE_CXX11
   struct once_flag
   {
- #if defined(__GNUC__)
- __attribute__((may_alias))
- #endif
- uintmax_t storage;
+ // The thread_detail::atomic_int_type storage is marked
+ // with this attribute in order to let the compiler know that it will alias this member
+ // and silence compilation warnings.
+ BOOST_THREAD_ATTRIBUTE_MAY_ALIAS thread_detail::atomic_int_type storage;
   };
 
   #define BOOST_ONCE_INIT {0}
 
+ namespace thread_detail
+ {
+ inline atomic_type& get_atomic_storage(once_flag& flag) BOOST_NOEXCEPT
+ {
+ return reinterpret_cast< atomic_type& >(flag.storage);
+ }
+
+ }
+
 #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
 
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
+
 #ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES
 
   template<typename Function, class ...ArgTypes>
@@ -76,28 +124,10 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
-#if defined BOOST_THREAD_PROVIDES_INVOKE
- detail::invoke(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
- detail::invoke<void>(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#else
- boost::bind(
+ BOOST_THREAD_INVOKE_RET_VOID(
                         thread_detail::decay_copy(boost::forward<Function>(f)),
                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- )();
-#endif
-#else
- f(
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#endif
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -135,11 +165,7 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1)();
-#else
- f(p1);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -158,11 +184,7 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2)();
-#else
- f(p1,p2);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -181,11 +203,7 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2,p3)();
-#else
- f(p1,p2,p3);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f, p1, p2, p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -223,17 +241,10 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
+ BOOST_THREAD_INVOKE_RET_VOID(
             thread_detail::decay_copy(boost::forward<Function>(f)),
             thread_detail::decay_copy(boost::forward<T1>(p1))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1))
- );
-#endif
-
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -251,18 +262,11 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
+ BOOST_THREAD_INVOKE_RET_VOID(
             thread_detail::decay_copy(boost::forward<Function>(f)),
             thread_detail::decay_copy(boost::forward<T1>(p1)),
             thread_detail::decay_copy(boost::forward<T1>(p2))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
- );
-#endif
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
       }
       BOOST_CATCH (...)
       {
@@ -280,20 +284,12 @@
     {
       BOOST_TRY
       {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
+ BOOST_THREAD_INVOKE_RET_VOID(
             thread_detail::decay_copy(boost::forward<Function>(f)),
             thread_detail::decay_copy(boost::forward<T1>(p1)),
             thread_detail::decay_copy(boost::forward<T1>(p2)),
             thread_detail::decay_copy(boost::forward<T1>(p3))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2)),
- thread_detail::decay_copy(boost::forward<T1>(p3))
- );
-#endif
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
 
       }
       BOOST_CATCH (...)

Modified: branches/release/boost/thread/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/shared_mutex.hpp (original)
+++ branches/release/boost/thread/shared_mutex.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -18,6 +18,7 @@
 #include <boost/thread/win32/shared_mutex.hpp>
 #endif
 #elif defined(BOOST_THREAD_PLATFORM_PTHREAD)
+//#include <boost/thread/v2/shared_mutex.hpp>
 #include <boost/thread/pthread/shared_mutex.hpp>
 #else
 #error "Boost threads unavailable on this platform"

Modified: branches/release/boost/thread/synchronized_value.hpp
==============================================================================
--- branches/release/boost/thread/synchronized_value.hpp (original)
+++ branches/release/boost/thread/synchronized_value.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -18,6 +18,17 @@
 #include <boost/thread/lock_factories.hpp>
 #include <boost/thread/strict_lock.hpp>
 #include <boost/utility/swap.hpp>
+#include <boost/utility/declval.hpp>
+//#include <boost/type_traits.hpp>
+//#include <boost/thread/detail/is_nothrow_default_constructible.hpp>
+//#if ! defined BOOST_NO_CXX11_HDR_TYPE_TRAITS
+//#include <type_traits>
+//#endif
+
+#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+#include <tuple> // todo change to <boost/tuple.hpp> once Boost.Tuple or Boost.Fusion provides Move semantics.
+#include <functional>
+#endif
 
 #include <boost/config/abi_prefix.hpp>
 
@@ -25,29 +36,44 @@
 {
 
   /**
+ * strict lock providing a const pointer access to the synchronized value type.
    *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
    */
   template <typename T, typename Lockable = mutex>
   class const_strict_lock_ptr
   {
   public:
     typedef T value_type;
- typedef Lockable lockable_type;
+ typedef Lockable mutex_type;
   protected:
 
- // this should be a strict_lock, but we need to be able to return it.
- boost::unique_lock<lockable_type> lk_;
+ // this should be a strict_lock, but unique_lock is needed to be able to return it.
+ boost::unique_lock<mutex_type> lk_;
     T const& value_;
 
   public:
     BOOST_THREAD_MOVABLE_ONLY( const_strict_lock_ptr )
 
- const_strict_lock_ptr(T const& value, Lockable & mtx) :
- lk_(mtx), value_(value)
+ /**
+ * @param value constant reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_strict_lock_ptr(T const& val, Lockable & mtx) :
+ lk_(mtx), value_(val)
     {
     }
-
- const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other)
+ const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag) BOOST_NOEXCEPT :
+ lk_(mtx, tag), value_(val)
+ {
+ }
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ const_strict_lock_ptr(BOOST_THREAD_RV_REF(const_strict_lock_ptr) other) BOOST_NOEXCEPT
     : lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
     {
     }
@@ -56,11 +82,17 @@
     {
     }
 
+ /**
+ * @return a constant pointer to the protected value
+ */
     const T* operator->() const
     {
       return &value_;
     }
 
+ /**
+ * @return a constant reference to the protected value
+ */
     const T& operator*() const
     {
       return value_;
@@ -69,7 +101,10 @@
   };
 
   /**
+ * strict lock providing a pointer access to the synchronized value type.
    *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
    */
   template <typename T, typename Lockable = mutex>
   class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
@@ -78,11 +113,24 @@
   public:
     BOOST_THREAD_MOVABLE_ONLY( strict_lock_ptr )
 
- strict_lock_ptr(T & value, Lockable & mtx) :
- base_type(value, mtx)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ strict_lock_ptr(T & val, Lockable & mtx) :
+ base_type(val, mtx)
+ {
+ }
+ strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag) :
+ base_type(val, mtx, tag)
     {
     }
 
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
     strict_lock_ptr(BOOST_THREAD_RV_REF(strict_lock_ptr) other)
     : base_type(boost::move(static_cast<base_type&>(other)))
     {
@@ -92,11 +140,17 @@
     {
     }
 
+ /**
+ * @return a pointer to the protected value
+ */
     T* operator->()
     {
       return const_cast<T*>(&this->value_);
     }
 
+ /**
+ * @return a reference to the protected value
+ */
     T& operator*()
     {
       return const_cast<T&>(this->value_);
@@ -104,8 +158,35 @@
 
   };
 
+ template <typename SV>
+ struct synchronized_value_strict_lock_ptr
+ {
+ typedef strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+
+ template <typename SV>
+ struct synchronized_value_strict_lock_ptr<const SV>
+ {
+ typedef const_strict_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
   /**
+ * unique_lock providing a const pointer access to the synchronized value type.
+ *
+ * An object of type const_unique_lock_ptr is a unique_lock that provides a const pointer access to the synchronized value type.
+ * As unique_lock controls the ownership of a lockable object within a scope.
+ * Ownership of the lockable object may be acquired at construction or after construction,
+ * and may be transferred, after acquisition, to another const_unique_lock_ptr object.
+ * Objects of type const_unique_lock_ptr are not copyable but are movable.
+ * The behavior of a program is undefined if the mutex and the value type
+ * pointed do not exist for the entire remaining lifetime of the const_unique_lock_ptr object.
+ * The supplied Mutex type shall meet the BasicLockable requirements.
    *
+ * @note const_unique_lock_ptr<T, Lockable> meets the Lockable requirements.
+ * If Lockable meets the TimedLockable requirements, const_unique_lock_ptr<T,Lockable>
+ * also meets the TimedLockable requirements.
+ *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
    */
   template <typename T, typename Lockable = mutex>
   class const_unique_lock_ptr : public unique_lock<Lockable>
@@ -113,44 +194,85 @@
     typedef unique_lock<Lockable> base_type;
   public:
     typedef T value_type;
- typedef Lockable lockable_type;
+ typedef Lockable mutex_type;
   protected:
     T const& value_;
 
   public:
     BOOST_THREAD_MOVABLE_ONLY(const_unique_lock_ptr)
 
- const_unique_lock_ptr(T const& value, Lockable & mtx)
- : base_type(mtx), value_(value)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ *
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
+ *
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx)
+ : base_type(mtx), value_(val)
     {
     }
- const_unique_lock_ptr(T const& value, Lockable & mtx, adopt_lock_t)
- : base_type(mtx, adopt_lock), value_(value)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
+ * @requires The calling thread own the mutex.
+ * @effects stores a reference to it and to the value type @c value taking ownership.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, adopt_lock), value_(val)
     {
     }
- const_unique_lock_ptr(T const& value, Lockable & mtx, defer_lock_t)
- : base_type(mtx, defer_lock), value_(value)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type defer_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value c.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, defer_lock), value_(val)
     {
     }
- const_unique_lock_ptr(T const& value, Lockable & mtx, try_to_lock_t)
- : base_type(mtx, try_to_lock), value_(value)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
+ * @requires If mutex_type is not a recursive mutex the calling thread does not own the mutex.
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ const_unique_lock_ptr(T const& val, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
+ : base_type(mtx, try_to_lock), value_(val)
     {
     }
- const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other)
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ const_unique_lock_ptr(BOOST_THREAD_RV_REF(const_unique_lock_ptr) other) BOOST_NOEXCEPT
     : base_type(boost::move(static_cast<base_type&>(other))), value_(BOOST_THREAD_RV(other).value_)
     {
     }
 
+ /**
+ * @effects If owns calls unlock() on the owned mutex.
+ */
     ~const_unique_lock_ptr()
     {
     }
 
+ /**
+ * @return a constant pointer to the protected value
+ */
     const T* operator->() const
     {
       BOOST_ASSERT (this->owns_lock());
       return &value_;
     }
 
+ /**
+ * @return a constant reference to the protected value
+ */
     const T& operator*() const
     {
       BOOST_ASSERT (this->owns_lock());
@@ -160,7 +282,10 @@
   };
 
   /**
+ * unique lock providing a pointer access to the synchronized value type.
    *
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
    */
   template <typename T, typename Lockable = mutex>
   class unique_lock_ptr : public const_unique_lock_ptr<T, Lockable>
@@ -168,27 +293,54 @@
     typedef const_unique_lock_ptr<T, Lockable> base_type;
   public:
     typedef T value_type;
- typedef Lockable lockable_type;
+ typedef Lockable mutex_type;
 
     BOOST_THREAD_MOVABLE_ONLY(unique_lock_ptr)
 
- unique_lock_ptr(T & value, Lockable & mtx)
- : base_type(value, mtx)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @effects locks the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ unique_lock_ptr(T & val, Lockable & mtx)
+ : base_type(val, mtx)
     {
     }
- unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type adopt_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value taking ownership.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, adopt_lock_t) BOOST_NOEXCEPT
     : base_type(value, mtx, adopt_lock)
     {
     }
- unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type defer_lock_t used to differentiate the constructor.
+ * @effects stores a reference to it and to the value type @c value c.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, defer_lock_t) BOOST_NOEXCEPT
     : base_type(value, mtx, defer_lock)
     {
     }
- unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t)
+ /**
+ * @param value reference of the value to protect.
+ * @param mtx reference to the mutex used to protect the value.
+ * @param tag of type try_to_lock_t used to differentiate the constructor.
+ * @effects try to lock the mutex @c mtx, stores a reference to it and to the value type @c value.
+ */
+ unique_lock_ptr(T & value, Lockable & mtx, try_to_lock_t) BOOST_NOEXCEPT
     : base_type(value, mtx, try_to_lock)
     {
     }
- unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other)
+ /**
+ * Move constructor.
+ * @effects takes ownership of the mutex owned by @c other, stores a reference to the mutex and the value type of @c other.
+ */
+ unique_lock_ptr(BOOST_THREAD_RV_REF(unique_lock_ptr) other) BOOST_NOEXCEPT
     : base_type(boost::move(static_cast<base_type&>(other)))
     {
     }
@@ -197,12 +349,18 @@
     {
     }
 
+ /**
+ * @return a pointer to the protected value
+ */
     T* operator->()
     {
       BOOST_ASSERT (this->owns_lock());
       return const_cast<T*>(&this->value_);
     }
 
+ /**
+ * @return a reference to the protected value
+ */
     T& operator*()
     {
       BOOST_ASSERT (this->owns_lock());
@@ -212,25 +370,62 @@
 
   };
 
+ template <typename SV>
+ struct synchronized_value_unique_lock_ptr
+ {
+ typedef unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
+
+ template <typename SV>
+ struct synchronized_value_unique_lock_ptr<const SV>
+ {
+ typedef const_unique_lock_ptr<typename SV::value_type, typename SV::mutex_type> type;
+ };
   /**
- *
+ * cloaks a value type and the mutex used to protect it together.
+ * @param T the value type.
+ * @param Lockable the mutex type protecting the value type.
    */
   template <typename T, typename Lockable = mutex>
   class synchronized_value
   {
+
+#if ! defined(BOOST_THREAD_NO_MAKE_UNIQUE_LOCKS)
+#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+ template <typename ...SV>
+ friend std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
+#else
+ template <typename SV1, typename SV2>
+ friend std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2);
+ template <typename SV1, typename SV2, typename SV3>
+ friend std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3);
+#endif
+#endif
+
   public:
     typedef T value_type;
- typedef Lockable lockable_type;
+ typedef Lockable mutex_type;
   private:
     T value_;
- mutable lockable_type mtx_;
+ mutable mutex_type mtx_;
   public:
+ // construction/destruction
     /**
      * Default constructor.
      *
- * Requires: T is DefaultConstructible
+ * @Requires: T is DefaultConstructible
      */
     synchronized_value()
+ //BOOST_NOEXCEPT_IF(is_nothrow_default_constructible<T>::value)
     : value_()
     {
     }
@@ -241,47 +436,50 @@
      * Requires: T is CopyConstructible
      */
     synchronized_value(T const& other)
+ //BOOST_NOEXCEPT_IF(is_nothrow_copy_constructible<T>::value)
     : value_(other)
     {
     }
 
     /**
- * Move Constructor from movable value.
+ * Move Constructor.
      *
- * Requires: T is Movable
+ * Requires: T is CopyMovable
      */
     synchronized_value(BOOST_THREAD_RV_REF(T) other)
+ //BOOST_NOEXCEPT_IF(is_nothrow_move_constructible<T>::value)
     : value_(boost::move(other))
     {
     }
 
     /**
- * Copy Constructor.
+ * Constructor from value type.
      *
      * Requires: T is DefaultConstructible and Assignable
      * Effects: Assigns the value on a scope protected by the mutex of the rhs. The mutex is not copied.
      */
     synchronized_value(synchronized_value const& rhs)
     {
- strict_lock<lockable_type> lk(rhs.mtx_);
+ strict_lock<mutex_type> lk(rhs.mtx_);
       value_ = rhs.value_;
     }
 
     /**
- * Move Constructor.
+ * Move Constructor from movable value type
      *
      */
     synchronized_value(BOOST_THREAD_RV_REF(synchronized_value) other)
     {
- strict_lock<lockable_type> lk(other.mtx_);
- value_= boost::move(other.value);
+ strict_lock<mutex_type> lk(other.mtx_);
+ value_= boost::move(other.value_);
     }
 
+ // mutation
     /**
      * Assignment operator.
      *
      * Effects: Copies the underlying value on a scope protected by the two mutexes.
- * The mutexes are not copied. The locks are acquired using lock, so deadlock is avoided.
+ * The mutex is not copied. The locks are acquired using lock, so deadlock is avoided.
      * For example, there is no problem if one thread assigns a = b and the other assigns b = a.
      *
      * Return: *this
@@ -292,8 +490,8 @@
       if(&rhs != this)
       {
         // auto _ = make_unique_locks(mtx_, rhs.mtx_);
- unique_lock<lockable_type> lk1(mtx_, defer_lock);
- unique_lock<lockable_type> lk2(rhs.mtx_, defer_lock);
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
         lock(lk1,lk2);
 
         value_ = rhs.value_;
@@ -305,15 +503,16 @@
      * Effects: The operator copies the value on a scope protected by the mutex.
      * Return: *this
      */
- synchronized_value& operator=(value_type const& value)
+ synchronized_value& operator=(value_type const& val)
     {
       {
- strict_lock<lockable_type> lk(mtx_);
- value_ = value;
+ strict_lock<mutex_type> lk(mtx_);
+ value_ = val;
       }
       return *this;
     }
 
+ //observers
     /**
      * Explicit conversion to value type.
      *
@@ -323,7 +522,7 @@
      */
     T get() const
     {
- strict_lock<lockable_type> lk(mtx_);
+ strict_lock<mutex_type> lk(mtx_);
       return value_;
     }
     /**
@@ -341,6 +540,30 @@
 #endif
 
     /**
+ * value type getter.
+ *
+ * Return: A constant reference to the protected value.
+ *
+ * Note: Not thread safe
+ *
+ */
+ T const& value() const
+ {
+ return value_;
+ }
+ /**
+ * mutex getter.
+ *
+ * Return: A constant reference to the protecting mutex.
+ *
+ * Note: Not thread safe
+ *
+ */
+ mutex_type const& mutex() const
+ {
+ return mtx_;
+ }
+ /**
      * Swap
      *
      * Effects: Swaps the data. Again, locks are acquired using lock(). The mutexes are not swapped.
@@ -354,20 +577,20 @@
         return;
       }
       // auto _ = make_unique_locks(mtx_, rhs.mtx_);
- unique_lock<lockable_type> lk1(mtx_, defer_lock);
- unique_lock<lockable_type> lk2(rhs.mtx_, defer_lock);
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
       lock(lk1,lk2);
       boost::swap(value_, rhs.value_);
     }
     /**
- * Swap with the underlying type
+ * Swap with the underlying value type
      *
      * Effects: Swaps the data on a scope protected by the mutex.
      */
     void swap(value_type & rhs)
     {
- strict_lock<lockable_type> lk(mtx_);
- boost::swap(value_, rhs.value_);
+ strict_lock<mutex_type> lk(mtx_);
+ boost::swap(value_, rhs);
     }
 
 
@@ -415,27 +638,53 @@
     {
       return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_)));
     }
- unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
- {
- return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
- }
     const_unique_lock_ptr<T,Lockable> unique_synchronize() const
     {
       return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_)));
     }
+ unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag)
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
+ }
     const_unique_lock_ptr<T,Lockable> unique_synchronize(defer_lock_t tag) const
     {
       return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, tag)));
     }
+ unique_lock_ptr<T,Lockable> defer_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> defer_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, defer_lock)));
+ }
+ unique_lock_ptr<T,Lockable> try_to_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> try_to_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, try_to_lock)));
+ }
+ unique_lock_ptr<T,Lockable> adopt_synchronize() BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
+ }
+ const_unique_lock_ptr<T,Lockable> adopt_synchronize() const BOOST_NOEXCEPT
+ {
+ return BOOST_THREAD_MAKE_RV_REF((const_unique_lock_ptr<T,Lockable>(value_, mtx_, adopt_lock)));
+ }
 
 
- private:
+#if ! defined __IBMCPP__
+ private:
+#endif
     class deref_value
     {
     private:
       friend class synchronized_value;
 
- boost::unique_lock<lockable_type> lk_;
+ boost::unique_lock<mutex_type> lk_;
       T& value_;
 
       explicit deref_value(synchronized_value& outer):
@@ -448,7 +697,7 @@
       deref_value(BOOST_THREAD_RV_REF(deref_value) other):
       lk_(boost::move(BOOST_THREAD_RV(other).lk_)),value_(BOOST_THREAD_RV(other).value_)
       {}
- operator T()
+ operator T&()
       {
         return value_;
       }
@@ -464,7 +713,7 @@
     private:
       friend class synchronized_value;
 
- boost::unique_lock<lockable_type> lk_;
+ boost::unique_lock<mutex_type> lk_;
       const T& value_;
 
       explicit const_deref_value(synchronized_value const& outer):
@@ -478,7 +727,7 @@
       lk_(boost::move(BOOST_THREAD_RV(other).lk_)), value_(BOOST_THREAD_RV(other).value_)
       {}
 
- operator T()
+ operator const T&()
       {
         return value_;
       }
@@ -495,8 +744,121 @@
       return BOOST_THREAD_MAKE_RV_REF(const_deref_value(*this));
     }
 
+ // io functions
+ /**
+ * @requires T is OutputStreamable
+ * @effects saves the value type on the output stream @c os.
+ */
+ template <typename OStream>
+ void save(OStream& os) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ os << value_;
+ }
+ /**
+ * @requires T is InputStreamable
+ * @effects loads the value type from the input stream @c is.
+ */
+ template <typename IStream>
+ void load(IStream& is) const
+ {
+ strict_lock<mutex_type> lk(mtx_);
+ is >> value_;
+ }
+
+ // relational operators
+ /**
+ * @requires T is EqualityComparable
+ *
+ */
+ bool operator==(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ == rhs.value_;
+ }
+ /**
+ * @requires T is LessThanComparable
+ *
+ */
+ bool operator<(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ < rhs.value_;
+ }
+ /**
+ * @requires T is GreaterThanComparable
+ *
+ */
+ bool operator>(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ > rhs.value_;
+ }
+ bool operator<=(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ <= rhs.value_;
+ }
+ bool operator>=(synchronized_value const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_, defer_lock);
+ unique_lock<mutex_type> lk2(rhs.mtx_, defer_lock);
+ lock(lk1,lk2);
+
+ return value_ >= rhs.value_;
+ }
+ bool operator==(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ == rhs;
+ }
+ bool operator!=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ != rhs;
+ }
+ bool operator<(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ < rhs;
+ }
+ bool operator<=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ <= rhs;
+ }
+ bool operator>(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ > rhs;
+ }
+ bool operator>=(value_type const& rhs) const
+ {
+ unique_lock<mutex_type> lk1(mtx_);
+
+ return value_ >= rhs;
+ }
+
   };
 
+ // Specialized algorithms
   /**
    *
    */
@@ -505,7 +867,133 @@
   {
     lhs.swap(rhs);
   }
+ template <typename T, typename L>
+ inline void swap(synchronized_value<T,L> & lhs, T & rhs)
+ {
+ lhs.swap(rhs);
+ }
+ template <typename T, typename L>
+ inline void swap(T & lhs, synchronized_value<T,L> & rhs)
+ {
+ rhs.swap(lhs);
+ }
+
+ //Hash support
+
+ template <class T> struct hash;
+ template <typename T, typename L>
+ struct hash<synchronized_value<T,L> >;
+
+ // Comparison with T
+ template <typename T, typename L>
+ bool operator!=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ {
+ return ! (lhs==rhs);
+ }
 
+ template <typename T, typename L>
+ bool operator==(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs==lhs;
+ }
+ template <typename T, typename L>
+ bool operator!=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs!=lhs;
+ }
+ template <typename T, typename L>
+ bool operator<(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs>=lhs;
+ }
+ template <typename T, typename L>
+ bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs>lhs;
+ }
+ template <typename T, typename L>
+ bool operator>(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs<=lhs;
+ }
+ template <typename T, typename L>
+ bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs)
+ {
+ return rhs<lhs;
+ }
+
+ /**
+ *
+ */
+ template <typename OStream, typename T, typename L>
+ inline OStream& operator<<(OStream& os, synchronized_value<T,L> const& rhs)
+ {
+ rhs.save(os);
+ return os;
+ }
+ template <typename IStream, typename T, typename L>
+ inline IStream& operator>>(IStream& is, synchronized_value<T,L> const& rhs)
+ {
+ rhs.load(is);
+ return is;
+ }
+
+#if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+#if ! defined BOOST_NO_CXX11_VARIADIC_TEMPLATES
+
+ template <typename ...SV>
+ std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv)
+ {
+ boost::lock(sv.mtx_ ...);
+ typedef std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> t_type;
+
+ return t_type(typename synchronized_value_strict_lock_ptr<SV>::type(sv.value_, sv.mtx_, adopt_lock) ...);
+ }
+#else
+
+ template <typename SV1, typename SV2>
+ std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2)
+ {
+ boost::lock(sv1.mtx_, sv2.mtx_);
+ typedef std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type
+ > t_type;
+
+ return t_type(
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock)
+ );
+
+ }
+ template <typename SV1, typename SV2, typename SV3>
+ std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ >
+ synchronize(SV1& sv1, SV2& sv2, SV3& sv3)
+ {
+ boost::lock(sv1.mtx_, sv2.mtx_);
+ typedef std::tuple<
+ typename synchronized_value_strict_lock_ptr<SV1>::type,
+ typename synchronized_value_strict_lock_ptr<SV2>::type,
+ typename synchronized_value_strict_lock_ptr<SV3>::type
+ > t_type;
+
+ return t_type(
+ typename synchronized_value_strict_lock_ptr<SV1>::type(sv1.value_, sv1.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV2>::type(sv2.value_, sv2.mtx_, adopt_lock),
+ typename synchronized_value_strict_lock_ptr<SV3>::type(sv3.value_, sv3.mtx_, adopt_lock)
+ );
+
+ }
+#endif
+#endif
 }
 
 #include <boost/config/abi_suffix.hpp>

Modified: branches/release/boost/thread/testable_mutex.hpp
==============================================================================
--- branches/release/boost/thread/testable_mutex.hpp (original)
+++ branches/release/boost/thread/testable_mutex.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -9,7 +9,7 @@
 
 #include <boost/thread/detail/config.hpp>
 
-#include <boost/thread/detail/thread.hpp>
+#include <boost/thread/thread_only.hpp>
 
 #include <boost/atomic.hpp>
 #include <boost/assert.hpp>
@@ -26,7 +26,7 @@
    *
    * Many mutex services (including boost::mutex) don't provide a way to ask,
    * "Do I already hold a lock on this mutex?"
- * Sometimes it is needed to know if a method like is_held to be available.
+ * Sometimes it is needed to know if a method like is_locked to be available.
    * This wrapper associates an arbitrary lockable type with a thread id that stores the ID of the thread that
    * currently holds the lockable. The thread id initially holds an invalid value that means no threads own the mutex.
    * When we acquire a lock, we set the thread id; and when we release a lock, we reset it back to its default no id state.
@@ -44,6 +44,8 @@
     /// Non copyable
     BOOST_THREAD_NO_COPYABLE(testable_mutex)
 
+ testable_mutex() : id_(thread::id()) {}
+
     void lock()
     {
       mtx_.lock();
@@ -52,7 +54,7 @@
 
     void unlock()
     {
- BOOST_ASSERT(is_locked(mtx_));
+ BOOST_ASSERT(is_locked_by_this_thread());
       id_ = thread::id();
       mtx_.unlock();
     }
@@ -70,40 +72,44 @@
       }
     }
 #ifdef BOOST_THREAD_USES_CHRONO
- template <class Rep, class Period>
- bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
- {
- if (mtx_.try_lock_for(rel_time))
- {
- id_ = this_thread::get_id();
- return true;
- }
- else
- {
- return false;
- }
- }
- template <class Clock, class Duration>
- bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
- {
- if (mtx_.try_lock_until(abs_time))
- {
- id_ = this_thread::get_id();
- return true;
- }
- else
- {
- return false;
- }
- }
+ template <class Rep, class Period>
+ bool try_lock_for(const chrono::duration<Rep, Period>& rel_time)
+ {
+ if (mtx_.try_lock_for(rel_time))
+ {
+ id_ = this_thread::get_id();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ template <class Clock, class Duration>
+ bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time)
+ {
+ if (mtx_.try_lock_until(abs_time))
+ {
+ id_ = this_thread::get_id();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
 #endif
 
- bool is_locked_by_this_thread()
+ bool is_locked_by_this_thread() const
     {
       return this_thread::get_id() == id_;
     }
+ bool is_locked() const
+ {
+ return ! (thread::id() == id_);
+ }
 
- bool get_id()
+ thread::id get_id() const
     {
       return id_;
     }

Modified: branches/release/boost/thread/v2/thread.hpp
==============================================================================
--- branches/release/boost/thread/v2/thread.hpp (original)
+++ branches/release/boost/thread/v2/thread.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -68,11 +68,8 @@
       using namespace chrono;
       if (d > duration<Rep, Period>::zero())
       {
- steady_clock::time_point c_now = steady_clock::now();
- do
- {
- sleep_until(system_clock::now() + ceil<nanoseconds>(d));
- } while (steady_clock::now() - c_now < d );
+ steady_clock::time_point c_timeout = steady_clock::now() + ceil<nanoseconds>(d);
+ sleep_until(c_timeout);
       }
     }
 

Modified: branches/release/boost/thread/win32/basic_timed_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/basic_timed_mutex.hpp (original)
+++ branches/release/boost/thread/win32/basic_timed_mutex.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -93,10 +93,13 @@
             {
                 for(;;)
                 {
- long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value);
+ bool const was_locked=(old_count&lock_flag_value) ? true : false;
+ long const new_count=was_locked?(old_count+1):(old_count|lock_flag_value);
                     long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count);
                     if(current==old_count)
                     {
+ if(was_locked)
+ old_count=new_count;
                         break;
                     }
                     old_count=current;

Modified: branches/release/boost/thread/win32/once.hpp
==============================================================================
--- branches/release/boost/thread/win32/once.hpp (original)
+++ branches/release/boost/thread/win32/once.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -5,7 +5,7 @@
 //
 // (C) Copyright 2005-7 Anthony Williams
 // (C) Copyright 2005 John Maddock
-// (C) Copyright 2011-2012 Vicente J. Botet Escriba
+// (C) Copyright 2011-2013 Vicente J. Botet Escriba
 //
 // Distributed under the Boost Software License, Version 1.0. (See
 // accompanying file LICENSE_1_0.txt or copy at
@@ -74,6 +74,17 @@
 #define BOOST_ONCE_INIT {0,0}
 #endif // BOOST_THREAD_PROVIDES_ONCE_CXX11
 
+#if defined BOOST_THREAD_PROVIDES_INVOKE
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
+#define BOOST_THREAD_INVOKE_RET_VOID detail::invoke<void>
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL
+#else
+#define BOOST_THREAD_INVOKE_RET_VOID boost::bind
+#define BOOST_THREAD_INVOKE_RET_VOID_CALL ()
+#endif
+
     namespace detail
     {
 #ifdef BOOST_NO_ANSI_APIS
@@ -261,8 +272,8 @@
         }
     }
 //#endif
- template<typename Function, class ...ArgTypes>
- inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ template<typename Function>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f)
     {
         // Try for a quick win: if the procedure has already been called
         // just skip through:
@@ -274,28 +285,54 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
-#if defined BOOST_THREAD_PROVIDES_INVOKE
- detail::invoke(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#elif defined BOOST_THREAD_PROVIDES_INVOKE_RET
- detail::invoke<void>(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#else
- boost::bind(
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, class A, class ...ArgTypes>
+ inline void call_once(once_flag& flag, BOOST_THREAD_RV_REF(Function) f, BOOST_THREAD_RV_REF(A) a, BOOST_THREAD_RV_REF(ArgTypes)... args)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(
                         thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<A>(a)),
                         thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- )();
-#endif
-#else
- f(
- thread_detail::decay_copy(boost::forward<ArgTypes>(args))...
- );
-#endif
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -327,7 +364,6 @@
     }
 #else
 #ifndef BOOST_MSVC
-
     template<typename Function>
     void call_once(once_flag& flag,Function f)
     {
@@ -384,11 +420,7 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1)();
-#else
- f(p1);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -431,11 +463,7 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2)();
-#else
- f(p1,p2);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -478,11 +506,181 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(f,p1,p2,p3)();
-#else
- f(p1,p2,p3);
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+#elif defined BOOST_NO_CXX11_RVALUE_REFERENCES
+
+ template<typename Function>
+ void call_once(once_flag& flag,Function const&f)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f();
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,Function const&f, T1 const&p1, T2 const&p2, T3 const&p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ BOOST_THREAD_INVOKE_RET_VOID(f,p1,p2,p3) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -617,7 +815,54 @@
                     {
                       f(
                           thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ );
+ }
+ BOOST_CATCH(...)
+ {
+ detail::rollback_once_region(flag, ctx);
+ BOOST_RETHROW
+ }
+ BOOST_CATCH_END
+ detail::commit_once_region(flag, ctx);
+ break;
+ }
+ if(!ctx.counted)
+ {
+ BOOST_INTERLOCKED_INCREMENT(&flag.count);
+ ctx.counted=true;
+ long status=::boost::detail::interlocked_read_acquire(&flag.status);
+ if(status==ctx.function_complete_flag_value)
+ {
+ break;
+ }
+ if(!ctx.event_handle)
+ {
+ ctx.event_handle=detail::create_once_event(ctx.mutex_name,&flag);
+ continue;
+ }
+ }
+ BOOST_VERIFY(!::boost::detail::win32::WaitForSingleObject(
+ ctx.event_handle,::boost::detail::win32::infinite));
+ }
+ }
+ template<typename Function, typename T1, typename T2, typename T3>
+ void call_once(once_flag& flag,void (*f)(BOOST_THREAD_RV_REF(T1),BOOST_THREAD_RV_REF(T2)), BOOST_THREAD_RV_REF(T1) p1, BOOST_THREAD_RV_REF(T2) p2, BOOST_THREAD_RV_REF(T3) p3)
+ {
+ // Try for a quick win: if the procedure has already been called
+ // just skip through:
+ detail::once_context ctx;
+ while(::boost::detail::interlocked_read_acquire(&flag.status)
+ !=ctx.function_complete_flag_value)
+ {
+ if(detail::enter_once_region(flag, ctx))
+ {
+ BOOST_TRY
+ {
+ f(
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
                       );
                     }
                     BOOST_CATCH(...)
@@ -706,16 +951,10 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -758,18 +997,11 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
                 }
                 BOOST_CATCH(...)
                 {
@@ -812,20 +1044,13 @@
             {
                 BOOST_TRY
                 {
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
- boost::bind(
- thread_detail::decay_copy(boost::forward<Function>(f)),
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2)),
- thread_detail::decay_copy(boost::forward<T1>(p3))
- )();
-#else
- f(
- thread_detail::decay_copy(boost::forward<T1>(p1)),
- thread_detail::decay_copy(boost::forward<T1>(p2)),
- thread_detail::decay_copy(boost::forward<T1>(p3))
- );
-#endif
+ BOOST_THREAD_INVOKE_RET_VOID(
+ thread_detail::decay_copy(boost::forward<Function>(f)),
+ thread_detail::decay_copy(boost::forward<T1>(p1)),
+ thread_detail::decay_copy(boost::forward<T2>(p2)),
+ thread_detail::decay_copy(boost::forward<T3>(p3))
+ ) BOOST_THREAD_INVOKE_RET_VOID_CALL;
+
                 }
                 BOOST_CATCH(...)
                 {

Modified: branches/release/boost/thread/win32/shared_mutex.hpp
==============================================================================
--- branches/release/boost/thread/win32/shared_mutex.hpp (original)
+++ branches/release/boost/thread/win32/shared_mutex.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -95,7 +95,7 @@
               detail::win32::release_semaphore(semaphores[exclusive_sem],LONG_MAX);
               boost::throw_exception(thread_resource_error());
             }
- state_data state_={0};
+ state_data state_={0,0,0,0,0,0};
             state=state_;
         }
 
@@ -471,6 +471,7 @@
                 {
                     for(;;)
                     {
+ bool must_notify = false;
                         state_data new_state=old_state;
                         if(new_state.shared_count || new_state.exclusive)
                         {
@@ -479,6 +480,7 @@
                                 if(!--new_state.exclusive_waiting)
                                 {
                                     new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
                                 }
                             }
                         }
@@ -488,6 +490,11 @@
                         }
 
                         state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
+
                         if(current_state==old_state)
                         {
                             break;
@@ -580,6 +587,7 @@
             {
               for(;;)
               {
+ bool must_notify = false;
                 state_data new_state=old_state;
                 if(new_state.shared_count || new_state.exclusive)
                 {
@@ -588,6 +596,7 @@
                     if(!--new_state.exclusive_waiting)
                     {
                       new_state.exclusive_waiting_blocked=false;
+ must_notify = true;
                     }
                   }
                 }
@@ -597,6 +606,10 @@
                 }
 
                 state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state);
+ if (must_notify)
+ {
+ BOOST_VERIFY(detail::win32::ReleaseSemaphore(semaphores[unlock_sem],1,0)!=0);
+ }
                 if(current_state==old_state)
                 {
                   break;
@@ -736,9 +749,11 @@
                     if(last_reader)
                     {
                         release_waiters(old_state);
- } else {
- release_waiters(old_state);
                     }
+ // #7720
+ //else {
+ // release_waiters(old_state);
+ //}
                     break;
                 }
                 old_state=current_state;

Modified: branches/release/boost/thread/win32/thread_data.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread_data.hpp (original)
+++ branches/release/boost/thread/win32/thread_data.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -165,7 +165,7 @@
 
         struct BOOST_SYMBOL_VISIBLE timeout
         {
- unsigned long start;
+ win32::ticks_type start;
             uintmax_t milliseconds;
             bool relative;
             boost::system_time abs_time;
@@ -173,14 +173,14 @@
             static unsigned long const max_non_infinite_wait=0xfffffffe;
 
             timeout(uintmax_t milliseconds_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()),
                 milliseconds(milliseconds_),
                 relative(true),
                 abs_time(boost::get_system_time())
             {}
 
             timeout(boost::system_time const& abs_time_):
- start(win32::GetTickCount()),
+ start(win32::GetTickCount64()),
                 milliseconds(0),
                 relative(false),
                 abs_time(abs_time_)
@@ -205,8 +205,8 @@
                 }
                 else if(relative)
                 {
- unsigned long const now=win32::GetTickCount();
- unsigned long const elapsed=now-start;
+ win32::ticks_type const now=win32::GetTickCount64();
+ win32::ticks_type const elapsed=now-start;
                     return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0);
                 }
                 else

Modified: branches/release/boost/thread/win32/thread_primitives.hpp
==============================================================================
--- branches/release/boost/thread/win32/thread_primitives.hpp (original)
+++ branches/release/boost/thread/win32/thread_primitives.hpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -17,6 +17,12 @@
 #include <boost/detail/interlocked.hpp>
 #include <algorithm>
 
+#ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+#if _WIN32_WINNT >= 0x0600
+#define BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+#endif
+#endif
+
 #if defined( BOOST_USE_WINDOWS_H )
 # include <windows.h>
 
@@ -26,6 +32,11 @@
     {
         namespace win32
         {
+#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+ typedef unsigned long long ticks_type;
+#else
+ typedef unsigned long ticks_type;
+#endif
             typedef ULONG_PTR ulong_ptr;
             typedef HANDLE handle;
             unsigned const infinite=INFINITE;
@@ -61,6 +72,11 @@
             using ::Sleep;
             using ::QueueUserAPC;
             using ::GetTickCount;
+#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+ using ::GetTickCount64;
+#else
+ inline ticks_type GetTickCount64() { return GetTickCount(); }
+#endif
         }
     }
 }
@@ -88,13 +104,18 @@
 # endif
 # endif
 
+
 namespace boost
 {
     namespace detail
     {
         namespace win32
         {
-
+#ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+ typedef unsigned long long ticks_type;
+#else
+ typedef unsigned long ticks_type;
+#endif
 # ifdef _WIN64
             typedef unsigned __int64 ulong_ptr;
 # else
@@ -133,7 +154,9 @@
                 __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
 
                 __declspec(dllimport) unsigned long __stdcall GetTickCount();
-
+# ifdef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+ __declspec(dllimport) ticks_type __stdcall GetTickCount64();
+# endif
 # ifndef UNDER_CE
                 __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
                 __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
@@ -150,6 +173,9 @@
                 using ::ResetEvent;
 # endif
             }
+# ifndef BOOST_THREAD_WIN32_HAS_GET_TICK_COUNT_64
+ inline ticks_type GetTickCount64() { return GetTickCount(); }
+# endif
         }
     }
 }

Modified: branches/release/libs/thread/build/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/build/Jamfile.v2 (original)
+++ branches/release/libs/thread/build/Jamfile.v2 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -49,8 +49,8 @@
       <toolset>gcc:<cxxflags>-Wno-long-long
       #<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
       #<define>BOOST_SYSTEM_NO_DEPRECATED
- #<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
-
+ #<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+
       <library>/boost/system//boost_system
        #-pedantic -ansi -std=gnu++0x -Wextra -fpermissive
         <warnings>all
@@ -59,12 +59,18 @@
         <toolset>gcc:<cxxflags>-Wno-long-long
         #<toolset>gcc:<cxxflags>-ansi
         #<toolset>gcc:<cxxflags>-fpermissive
+ <toolset>gcc:<cxxflags>-Wno-variadic-macros
+ #<toolset>gcc:<cxxflags>-Wunused-local-typedefs
+ <toolset>gcc:<cxxflags>-Wunused-function
 
         <toolset>darwin:<cxxflags>-Wextra
         <toolset>darwin:<cxxflags>-pedantic
         #<toolset>darwin:<cxxflags>-ansi
         <toolset>darwin:<cxxflags>-fpermissive
         <toolset>darwin:<cxxflags>-Wno-long-long
+ <toolset>darwin:<cxxflags>-Wno-variadic-macros
+ #<toolset>darwin:<cxxflags>-Wunused-local-typedefs
+ <toolset>darwin:<cxxflags>-Wunused-function
 
         #<toolset>pathscale:<cxxflags>-Wextra
         <toolset>pathscale:<cxxflags>-Wno-long-long
@@ -75,6 +81,8 @@
         #<toolset>clang:<cxxflags>-ansi
         #<toolset>clang:<cxxflags>-fpermissive
         <toolset>clang:<cxxflags>-Wno-long-long
+ <toolset>clang:<cxxflags>-Wunused-function
+ <toolset>clang:<cxxflags>-Wno-variadic-macros
 
         <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
         <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
@@ -82,6 +90,7 @@
         <toolset>gcc-mingw-4.6.3:<cxxflags>-fdiagnostics-show-option
         <toolset>gcc-mingw-4.7.0:<cxxflags>-fdiagnostics-show-option
         <toolset>gcc-mingw-4.8.0:<cxxflags>-fdiagnostics-show-option
+ #<toolset>gcc:<cxxflags>-Wno-missing-field-initializers
 
         <toolset>darwin-4.6.2:<cxxflags>-Wno-delete-non-virtual-dtor
         <toolset>darwin-4.7.0:<cxxflags>-Wno-delete-non-virtual-dtor
@@ -93,7 +102,7 @@
         <toolset>clang-3.0:<cxxflags>-Wno-delete-non-virtual-dtor
         #<toolset>clang-3.0:<cxxflags>-Wno-unused-function
         #<toolset>clang-3.0:<cxxflags>-Wno-unused-variable
-
+
 # Note: Some of the remarks from the Intel compiler are disabled
 # remark #193: zero used for undefined preprocessing identifier "XXX"
 # remark #304: access control not specified ("public" by default)
@@ -104,7 +113,9 @@
         <toolset>intel:<cxxflags>-wd193,304,383,444
         <toolset>intel:<cxxflags>-wd593,981
         <toolset>intel:<cxxflags>-wd1418
- <toolset>intel:<cxxflags>-wd2415
+ <toolset>intel:<cxxflags>-wd2415
+
+ <toolset>msvc:<cxxflags>/wd4512
 
 
     # : default-build <threading>multi
@@ -115,7 +126,7 @@
       <link>shared:<define>BOOST_THREAD_BUILD_DLL=1
       #<define>BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED
       #<define>BOOST_SYSTEM_NO_DEPRECATED
- #<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ #<define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
       <library>/boost/system//boost_system
     ;
 
@@ -225,11 +236,11 @@
         }
     }
 
- if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
+ if ! <toolset>vacpp in $(properties) || <toolset-vacpp:version>11.1 in $(properties) || <toolset-vacpp:version>12.1.0.1 in $(properties) || <toolset-vacpp:version>12.1 in $(properties)
     {
       result += <library>/boost/chrono//boost_chrono ;
     }
-
+
     return $(result) ;
 }
 
@@ -254,8 +265,8 @@
         }
     }
     result += <define>BOOST_THREAD_DONT_USE_CHRONO ;
-
- if <toolset>pgi in $(properties) || <toolset>vacpp in $(properties)
+
+ if <toolset>pgi in $(properties) || <toolset>vacpp in $(properties)
     {
       result += <library>/boost/atomic//boost_atomic ;
     }

Modified: branches/release/libs/thread/doc/barrier.qbk
==============================================================================
--- branches/release/libs/thread/doc/barrier.qbk (original)
+++ branches/release/libs/thread/doc/barrier.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -63,7 +63,10 @@
 
 [[Returns:] [`true` for exactly one thread from each batch of waiting threads, `false` otherwise.]]
 
-[[Throws:] [__thread_resource_error__ if an error occurs.]]
+[[Throws:] [__thread_resource_error__ if an error occurs. __thread_interrupted__ if the wait was interrupted by a call to
+__interrupt__ on the __thread__ object associated with the current thread of execution.]]
+
+[[Notes:] [`wait()` is an ['interruption point].]]
 
 ]
 

Modified: branches/release/libs/thread/doc/changes.qbk
==============================================================================
--- branches/release/libs/thread/doc/changes.qbk (original)
+++ branches/release/libs/thread/doc/changes.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -8,8 +8,28 @@
 
 [section:changes History]
 
+[heading Version 4.1.0 - boost 1.54]
+
+* [@http://svn.boost.org/trac/boost/ticket/7285 #7285] C++11 compliance: Allow to pass movable arguments for call_once.
+* [@http://svn.boost.org/trac/boost/ticket/7449 #7449] Synchro: Add a synchronized value class
+
 [heading Version 4.0.0 - boost 1.53]
 
+* [@http://svn.boost.org/trac/boost/ticket/4882 #4882] Win32 shared_mutex does not handle timeouts correctly.
+* [@http://svn.boost.org/trac/boost/ticket/6652 #6652] Boost.Thread shared_mutex.hpp:50:99: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
+* [@http://svn.boost.org/trac/boost/ticket/7720 #7720] exception lock_error while intensive locking/unlocking of mutex
+* [@http://svn.boost.org/trac/boost/ticket/7755 #7755] Thread: deadlock with shared_mutex on Windows
+* [@http://svn.boost.org/trac/boost/ticket/4882 #8070] prefer GetTickCount64 over GetTickCount
+* [@http://svn.boost.org/trac/boost/ticket/8136 #8136] boost::this_thread::sleep_for() sleeps longer than it should in Windows
+* [@http://svn.boost.org/trac/boost/ticket/8212 #8212] Boost thread compilation error on Solaris 10
+* [@http://svn.boost.org/trac/boost/ticket/8237 #8237] fix documentation for 'thread_group'
+* [@http://svn.boost.org/trac/boost/ticket/8239 #8239] barrier::wait() not marked as interruption_point
+
+
+[*New Features:]
+
+[*Fixed Bugs:]
+
 [/
 [*Breaking changes:]
 
@@ -41,6 +61,7 @@
 See BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK and BOOST_THREAD_DONT_PROVIDE_SIGNATURE_PACKAGED_TASK.
 
 * [@http://svn.boost.org/trac/boost/ticket/7282 #7282] C++11 compliance: Add packaged_task::make_ready_at_thread_exit function
+* [@http://svn.boost.org/trac/boost/ticket/7285 #7285] C++11 compliance: Allow to pass movable arguments for call_once
 
 * [@http://svn.boost.org/trac/boost/ticket/7412 #7412] C++11 compliance: Add async from movable callable and movable arguments
 Provided when BOOST_THREAD_PROVIDES_VARIADIC_THREAD and BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK are defined (Default value from Boost 1.55):
@@ -63,11 +84,13 @@
 
 [*Fixed Bugs:]
 
+* [@http://svn.boost.org/trac/boost/ticket/5752 #5752] boost::call_once() is unreliable on some platforms
 * [@http://svn.boost.org/trac/boost/ticket/7464 #7464] BOOST_TEST(n_alive == 1); fails due to race condition in a regression test tool.
 * [@http://svn.boost.org/trac/boost/ticket/7657 #7657] Serious performance and memory consumption hit if condition_variable methods condition notify_one or notify_all is used repeatedly.
 * [@http://svn.boost.org/trac/boost/ticket/7665 #7665] this_thread::sleep_for no longer uses steady_clock in thread.
 * [@http://svn.boost.org/trac/boost/ticket/7668 #7668] thread_group::join_all() should check whether its threads are joinable.
 * [@http://svn.boost.org/trac/boost/ticket/7669 #7669] thread_group::join_all() should catch resource_deadlock_would_occur.
+* [@http://svn.boost.org/trac/boost/ticket/7671 #7671] Error including boost/thread.hpp header on iOS.
 * [@http://svn.boost.org/trac/boost/ticket/7672 #7672] lockable_traits.hpp syntax error: "defined" token misspelled.
 * [@http://svn.boost.org/trac/boost/ticket/7798 #7798] boost::future set_wait_callback thread safety issues.
 * [@http://svn.boost.org/trac/boost/ticket/7808 #7808] Incorrect description of effects for this_thread::sleep_for and this_thread::sleep_until.
@@ -75,6 +98,8 @@
 * [@http://svn.boost.org/trac/boost/ticket/7874 #7874] compile warning: thread.hpp:342: warning: type attributes are honored only at type definition.
 * [@http://svn.boost.org/trac/boost/ticket/7875 #7875] BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED should not be enabled by default.
 * [@http://svn.boost.org/trac/boost/ticket/7882 #7882] wrong exception text from condition_variable::wait(unique_lock<mutex>&).
+* [@http://svn.boost.org/trac/boost/ticket/7890 #7890] thread::do_try_join_until() is missing a return type.
+
 
 
 [heading Version 3.1.0 - boost 1.52]

Modified: branches/release/libs/thread/doc/compliance.qbk
==============================================================================
--- branches/release/libs/thread/doc/compliance.qbk (original)
+++ branches/release/libs/thread/doc/compliance.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -12,7 +12,7 @@
 
 [table C++11 standard Conformance
     [[Section] [Description] [Status] [Comments] [Ticket]]
- [[30] [Thread support library] [Partial] [-] [-]]
+ [[30] [Thread support library] [Yes] [-] [-]]
     [[30.1] [General] [-] [-] [-]]
     [[30.2] [Requirements] [-] [-] [-]]
     [[30.2.1] [Template parameter names] [-] [-] [-]]
@@ -53,16 +53,16 @@
     [[30.4.2.2.3] [unique_lock modifiers] [Yes] [-] [-]]
     [[30.4.2.2.4] [unique_lock observers] [Yes] [] [-]]
     [[30.4.3] [Generic locking algorithms] [Partial] [variadic] [#6227]]
- [[30.4.4] [Call once] [Partial] [call_once] [#7285]]
+ [[30.4.4] [Call once] [Yes] [-] [-]]
     [[30.4.4.1] [Struct once_flag] [Yes] [-] [-]]
- [[30.4.4.2] [Function call_once] [Partial] [interface] [#7285]]
+ [[30.4.4.2] [Function call_once] [Yes] [-] [-]]
     [[30.5] [Condition variables] [Yes] [-] [-]]
     [[30.5.1] [Class condition_variable] [Yes] [-] [-]]
     [[30.5.2] [Class condition_variable_any] [Yes] [-] [-]]
- [[30.6] [Futures] [Partial] [noexcept] [#7279]]
+ [[30.6] [Futures] [Yes] [-] [-]]
     [[30.6.1] [Overview] [Partial] [-] [-]]
     [[30.6.2] [Error handling] [Yes] [-] [-]]
- [[30.6.3] [Class future_error] [Partial] [noexcept] [#7279]]
+ [[30.6.3] [Class future_error] [-] [-] [-]]
     [[30.6.4] [Shared state] [-] [-] [-]]
     [[30.6.5] [Class template promise] [Yes] [-] [-]]
     [[30.6.6] [Class template future] [Yes] [-] [-]]

Modified: branches/release/libs/thread/doc/configuration.qbk
==============================================================================
--- branches/release/libs/thread/doc/configuration.qbk (original)
+++ branches/release/libs/thread/doc/configuration.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -31,7 +31,7 @@
     [[PROVIDES_ONCE_CXX11] [DONT_PROVIDE_ONCE_CXX11] [NO] [YES] [YES] ]
     [[USES_MOVE] [DONT_USE_MOVE] [NO] [YES] [YES] ]
 
- [[USES_DATETIME] [DONT_USE_DATETIME] [YES] [YES] [NO] ]
+ [[USES_DATETIME] [DONT_USE_DATETIME] [YES] [YES] [YES/NO] ]
     [[PROVIDES_THREAD_EQ] [DONT_PROVIDE_THREAD_EQ] [YES] [YES] [NO] ]
     [[PROVIDES_CONDITION] [DONT_PROVIDE_CONDITION] [YES] [YES] [NO] ]
     [[PROVIDES_NESTED_LOCKS] [DONT_PROVIDE_NESTED_LOCKS] [YES] [YES] [NO] ]
@@ -69,8 +69,10 @@
 * __timed_lock_ref__
 
 
-When `BOOST_THREAD_VERSION<=3` define `BOOST_THREAD_DONT_USE_DATETIME ` if you don't want to use Boost.DateTime related interfaces.
-When `BOOST_THREAD_VERSION>3` define `BOOST_THREAD_USES_DATETIME ` if you want to use Boost.DateTime related interfaces.
+When `BOOST_THREAD_VERSION<=3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `BOOST_THREAD_DONT_USE_DATETIME` if you don't want to use Boost.DateTime related interfaces.
+When `BOOST_THREAD_VERSION>3` && defined BOOST_THREAD_PLATFORM_PTHREAD define `BOOST_THREAD_USES_DATETIME` if you want to use Boost.DateTime related interfaces.
+
+When defined BOOST_THREAD_PLATFORM_WIN32 BOOST_THREAD_USES_DATETIME is defined by default.
 
 [endsect]
 
@@ -343,7 +345,7 @@
 
 * Breaking change `BOOST_THREAD_DONT_PROVIDE_PROMISE_LAZY`
 
-The default value for `BOOST_THREAD_VERSION` will be changed to 3 since Boost 1.54.
+[/The default value for `BOOST_THREAD_VERSION` will be changed to 3 since Boost 1.54.]
 
 The user can request the version 4 by defining `BOOST_THREAD_VERSION` to 4. In this case the following breaking or extending macros are defined if the opposite is not requested:
 
@@ -354,7 +356,7 @@
 * Breaking change `BOOST_THREAD_DONT_USE_DATETIME`
 
 
-The default value for `BOOST_THREAD_VERSION` will be changed to 4 since Boost 1.56.
+[/The default value for `BOOST_THREAD_VERSION` will be changed to 4 since Boost 1.58.]
 
 [endsect]
 

Modified: branches/release/libs/thread/doc/internal_locking.qbk
==============================================================================
--- branches/release/libs/thread/doc/internal_locking.qbk (original)
+++ branches/release/libs/thread/doc/internal_locking.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -55,6 +55,9 @@
 
 From time to time, the `bankAgent` will deposit $500 in `JoesAccount`. Joe will similarly withdraw $100 from his account. These sentences describe that the bankAgent and Joe are executed concurrently.
 
+[endsect]
+[section Internal locking]
+
 The above example works well as long as the bankAgent and Joe doesn't access JoesAccount at the same time. There is, however, no guarantee that this will not happen. We may use a mutex to guarantee exclusive access to each bank.
 
   class BankAccount {
@@ -105,6 +108,9 @@
 
 The object-level locking idiom doesn't cover the entire richness of a threading model. For example, the model above is quite deadlock-prone when you try to coordinate multi-object transactions. Nonetheless, object-level locking is useful in many cases, and in combination with other mechanisms can provide a satisfactory solution to many threaded access problems in object-oriented programs.
 
+[endsect]
+[section Internal and external locking]
+
 The BankAccount class above uses internal locking. Basically, a class that uses internal locking guarantees that any concurrent calls to its public member functions don't corrupt an instance of that class. This is typically ensured by having each public member function acquire a lock on the object upon entry. This way, for any given object of that class, there can be only one member function call active at any moment, so the operations are nicely serialized.
 
 This approach is reasonably easy to implement and has an attractive simplicity. Unfortunately, "simple" might sometimes morph into "simplistic."
@@ -203,6 +209,24 @@
       // ...
   };
 
+The caller-ensured locking approach is more flexible and the most efficient, but very dangerous. In an implementation using caller-ensured locking, BankAccount still holds a mutex, but its member functions don't manipulate it at all. Deposit and Withdraw are not thread-safe anymore. Instead, the client code is responsible for locking BankAccount properly.
+
+ class BankAccount
+ : public basic_lockable_adapter<boost:mutex> {
+ int balance_;
+ public:
+ void Deposit(int amount) {
+ balance_ += amount;
+ }
+ void Withdraw(int amount) {
+ balance_ -= amount;
+ }
+ };
+
+Obviously, the caller-ensured locking approach has a safety problem. BankAccount's implementation code is finite, and easy to reach and maintain, but there's an unbounded amount of client code that manipulates BankAccount objects. In designing applications, it's important to differentiate between requirements imposed on bounded code and unbounded code. If your class makes undue requirements on unbounded code, that's usually a sign that encapsulation is out the window.
+
+To conclude, if in designing a multi-threaded class you settle on internal locking, you expose yourself to inefficiency or deadlocks. On the other hand, if you rely on caller-provided locking, you make your class error-prone and difficult to use. Finally, external locking completely avoids the issue by leaving it all to the client code.
+
 
 [endsect]
 
@@ -440,11 +464,6 @@
 [endsect] [/Monitors]
 ]
 
-[section Synchronized variables]
-[/include synchronized_value.qbk]
-[endsect] [/Synchronized variables]
-
-
 [endsect] [/Internal Locking]
 
 

Modified: branches/release/libs/thread/doc/mutex_concepts.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutex_concepts.qbk (original)
+++ branches/release/libs/thread/doc/mutex_concepts.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -1134,7 +1134,7 @@
 The following classes are models of `StrictLock`:
 
 * strict_lock: ensured by construction,
-* nested_strict_lock: ensured by construction,
+* nested_strict_lock: "sur parolle" as the user could use adopt_lock_t on unique_lock constructor overload without having locked the mutex,
 * __lock_guard__: "sur parolle" as the user could use adopt_lock_t constructor overload without having locked the mutex.
 
 [endsect] [/ Models]
@@ -2002,6 +2002,8 @@
     {
     public:
         typedef BasicLockable mutex_type;
+ strict_lock(strict_lock const& m_) = delete;
+ strict_lock& operator=(strict_lock const& m_) = delete;
         explicit strict_lock(mutex_type& m_);
         ~strict_lock();
 
@@ -2052,6 +2054,8 @@
     {
     public:
         typedef BasicLockable mutex_type;
+ nested_strict_lock(nested_strict_lock const& m_) = delete;
+ nested_strict_lock& operator=(nested_strict_lock const& m_) = delete;
         explicit nested_strict_lock(Lock& lk),
         ~nested_strict_lock() noexcept;
 
@@ -2154,6 +2158,235 @@
   
 [endsect]
 
+[section:lock_ptrs Locking pointers]
+
+ // #include <boost/thread/synchroniezd_value.hpp>
+ // #include <boost/thread/strict_lock_ptr.hpp>
+
+ namespace boost
+ {
+
+ template<typename T, typename Lockable = mutex>
+ class strict_lock_ptr;
+ template<typename T, typename Lockable = mutex>
+ class const_strict_lock_ptr;
+ }
+
+
+[/
+ template<typename T, typename Lockable = mutex>
+ class unique_lock_ptr;
+ template<typename T, typename Lockable = mutex>
+ class const_unique_lock_ptr;
+
+]
+
+[section:const_strict_lock_ptr Class template `const_strict_lock_ptr `]
+
+ // #include <boost/thread/synchroniezd_value.hpp>
+ // #include <boost/thread/strict_lock_ptr.hpp>
+
+
+ template <typename T, typename Lockable = mutex>
+ class const_strict_lock_ptr
+ {
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+
+ const_strict_lock_ptr(const_strict_lock_ptr const& m_) = delete;
+ const_strict_lock_ptr& operator=(const_strict_lock_ptr const& m_) = delete;
+
+ const_strict_lock_ptr(T const& val, Lockable & mtx);
+ const_strict_lock_ptr(T const& val, Lockable & mtx, adopt_lock_t tag);
+
+ ~const_strict_lock_ptr();
+
+ const T* operator->() const;
+ const T& operator*() const;
+
+ };
+
+
+[section:constructor `const_strict_lock_ptr(T const&,Lockable&)`]
+
+
+ const_strict_lock_ptr(T const& val, Lockable & m);
+
+[variablelist
+
+[[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
+
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+
+]
+
+[endsect]
+[section:constructor_adopt `const_strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
+
+ const_strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
+
+[variablelist
+
+[[Effects:] [Stores a reference to it and to the value type `val`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[section:destructor `~const_strict_lock_ptr()`]
+
+ ~const_strict_lock_ptr();
+
+[variablelist
+
+[[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
+object passed to the constructor.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:indir `operator->() const`]
+
+ const T* operator->() const;
+
+
+[variablelist
+
+[[Return:] [return a constant pointer to the protected value.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:deref `operator*() const`]
+
+ const T& operator*() const;
+
+
+[variablelist
+
+[[Return:] [return a constant reference to the protected value.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect] [/ const_strict_lock_ptr ]
+
+[section:strict_lock_ptr Class template `strict_lock_ptr`]
+
+ // #include <boost/thread/synchroniezd_value.hpp>
+ // #include <boost/thread/strict_lock_ptr.hpp>
+
+ template <typename T, typename Lockable = mutex>
+ class strict_lock_ptr : public const_strict_lock_ptr<T,Lockable>
+ {
+ public:
+ strict_lock_ptr(strict_lock_ptr const& m_) = delete;
+ strict_lock_ptr& operator=(strict_lock_ptr const& m_) = delete;
+
+ strict_lock_ptr(T & val, Lockable & mtx);
+ strict_lock_ptr(T & val, Lockable & mtx, adopt_lock_t tag);
+ ~strict_lock_ptr();
+
+ T* operator->();
+ T& operator*();
+
+ };
+
+
+[section:constructor `strict_lock_ptr(T const&,Lockable&)`]
+
+
+ strict_lock_ptr(T const& val, Lockable & m);
+
+[variablelist
+
+[[Effects:] [Invokes [lock_ref_link `m.lock()`], stores a reference to it and to the value type `val`.]]
+
+[[Throws:] [Any exception thrown by the call to [lock_ref_link `m.lock()`].]]
+
+]
+
+[endsect]
+[section:constructor_adopt `strict_lock_ptr(T const&,Lockable&,adopt_lock_t)`]
+
+ strict_lock_ptr(T const& val, Lockable & m, adopt_lock_t tag);
+
+[variablelist
+
+[[Effects:] [Stores a reference to it and to the value type `val`.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[section:destructor `~strict_lock_ptr()`]
+
+ ~ strict_lock_ptr();
+
+[variablelist
+
+[[Effects:] [Invokes [unlock_ref_link `m.unlock()`] on the __lockable_concept_type__
+object passed to the constructor.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:indir `operator->()`]
+
+ T* operator->();
+
+
+[variablelist
+
+[[Return:] [return a pointer to the protected value.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:deref `operator*()`]
+
+ T& operator*();
+
+
+[variablelist
+
+[[Return:] [return a reference to the protected value.]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+[endsect] [/ strict_lock_ptr ]
+
+[endsect] [/ lock_ptrs ]
+
+
 [section Externally Locked]
 
   // #include <boost/thread/externally_locked.hpp>

Modified: branches/release/libs/thread/doc/mutexes.qbk
==============================================================================
--- branches/release/libs/thread/doc/mutexes.qbk (original)
+++ branches/release/libs/thread/doc/mutexes.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -239,3 +239,410 @@
 [include shared_mutex_ref.qbk]
 
 [endsect]
+
+[section:synchronized_value_ref Synchronized Values]
+
+
+ namespace boost
+ {
+
+ template<typename T, typename Lockable = mutex>
+ class synchronized_value;
+
+ // Specialized swap algorithm
+ template <typename T, typename L>
+ void swap(synchronized_value<T,L> & lhs, synchronized_value<T,L> & rhs);
+ template <typename T, typename L>
+ void swap(synchronized_value<T,L> & lhs, T & rhs);
+ template <typename T, typename L>
+ void swap(T & lhs, synchronized_value<T,L> & rhs);
+
+ // Hash support
+ template<typename T, typename L>
+ struct hash<synchronized_value<T,L> >;
+
+ // Comparison
+ template <typename T, typename L>
+ bool operator==(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ template <typename T, typename L>
+ bool operator!=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ template <typename T, typename L>
+ bool operator<(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ template <typename T, typename L>
+ bool operator<=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ template <typename T, typename L>
+ bool operator>(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+ template <typename T, typename L>
+ bool operator>=(synchronized_value<T,L> const&lhs, synchronized_value<T,L> const& rhs)
+
+ // Comparison with T
+ template <typename T, typename L>
+ bool operator==(T const& lhs, synchronized_value<T,L> const&rhs);
+ template <typename T, typename L>
+ bool operator!=(T const& lhs, synchronized_value<T,L> const&rhs);
+ template <typename T, typename L>
+ bool operator<(T const& lhs, synchronized_value<T,L> const&rhs);
+ template <typename T, typename L>
+ bool operator<=(T const& lhs, synchronized_value<T,L> const&rhs);
+ template <typename T, typename L>
+ bool operator>(T const& lhs, synchronized_value<T,L> const&rhs);
+ template <typename T, typename L>
+ bool operator>=(T const& lhs, synchronized_value<T,L> const&rhs);
+
+ template <typename T, typename L>
+ bool operator==(synchronized_value<T,L> const& lhs, T const& rhs);
+ template <typename T, typename L>
+ bool operator!=(synchronized_value<T,L> const& lhs, T const& rhs);
+ template <typename T, typename L>
+ bool operator<(synchronized_value<T,L> const& lhs, T const& rhs);
+ template <typename T, typename L>
+ bool operator<=(synchronized_value<T,L> const& lhs, T const& rhs);
+ template <typename T, typename L>
+ bool operator>(synchronized_value<T,L> const& lhs, T const& rhs);
+ template <typename T, typename L>
+ bool operator>=(synchronized_value<T,L> const& lhs, T const& rhs);
+
+ #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+ template <typename ...SV>
+ std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
+ #endif
+ }
+
+[section:synchronized_value Class `synchronized_value`]
+
+ #include <boost/thread/synchronized_value.hpp>
+
+ namespace boost
+ {
+
+ template<typename T, typename Lockable = mutex>
+ class synchronized_value
+ {
+ public:
+ typedef T value_type;
+ typedef Lockable mutex_type;
+
+ synchronized_value() noexept(is_nothrow_default_constructible<T>::value);
+ synchronized_value(T const& other) noexept(is_nothrow_copy_constructible<T>::value);
+ synchronized_value(T&& other) noexept(is_nothrow_move_constructible<T>::value);
+ synchronized_value(synchronized_value const& rhs);
+ synchronized_value(synchronized_value&& other);
+
+ // mutation
+ synchronized_value& operator=(synchronized_value const& rhs);
+ synchronized_value& operator=(value_type const& val);
+ void swap(synchronized_value & rhs);
+ void swap(value_type & rhs);
+
+ //observers
+ T get() const;
+ #if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ explicit operator T() const;
+ #endif
+
+ strict_lock_ptr<T,Lockable> operator->();
+ const_strict_lock_ptr<T,Lockable> operator->() const;
+ strict_lock_ptr<T,Lockable> synchronize();
+ const_strict_lock_ptr<T,Lockable> synchronize() const;
+
+ deref_value operator*();;
+ const_deref_value operator*() const;
+
+ private:
+ T value_; // for exposition only
+ mutable mutex_type mtx_; // for exposition only
+ };
+ }
+
+[variablelist
+
+[[Requires:] [`Lockable` is `Lockable`.]]
+
+]
+
+
+[section:constructor `synchronized_value()`]
+
+ synchronized_value() noexept(is_nothrow_default_constructible<T>::value);
+
+[variablelist
+
+[[Requires:] [`T` is `DefaultConstructible`.]]
+[[Effects:] [Default constructs the cloaked value_type]]
+
+[[Throws:] [Any exception thrown by `value_type()`.]]
+
+]
+
+[endsect]
+
+
+[section:constructor_vt `synchronized_value(T const&)`]
+
+ synchronized_value(T const& other) noexept(is_nothrow_copy_constructible<T>::value);
+
+[variablelist
+
+[[Requires:] [`T` is `CopyConstructible`.]]
+[[Effects:] [Copy constructs the cloaked value_type using the parameter `other`]]
+
+[[Throws:] [Any exception thrown by `value_type(other)`.]]
+
+]
+
+[endsect]
+
+[section:copy_cons `synchronized_value(synchronized_value const&)`]
+
+ synchronized_value(synchronized_value const& rhs);
+
+[variablelist
+
+[[Requires:] [`T` is `DefaultConstructible` and `Assignable`.]]
+[[Effects:] [Assigns the value on a scope protected by the mutex of the rhs. The mutex is not copied.]]
+
+[[Throws:] [Any exception thrown by `value_type()` or `value_type& operator=(value_type&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+[section:move_vt `synchronized_value(T&&)`]
+
+ synchronized_value(T&& other) noexept(is_nothrow_move_constructible<T>::value);
+
+[variablelist
+
+[[Requires:] [`T` is `CopyMovable `.]]
+[[Effects:] [Move constructs the cloaked value_type]]
+
+[[Throws:] [Any exception thrown by `value_type(value_type&&)`.]]
+
+]
+
+[endsect]
+
+[section:move `synchronized_value(synchronized_value&&)`]
+
+ synchronized_value(synchronized_value&& other);
+
+[variablelist
+
+[[Requires:] [`T` is `CopyMovable `.]]
+[[Effects:] [Move constructs the cloaked value_type]]
+
+[[Throws:] [Any exception thrown by `value_type(value_type&&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+[section:assign `operator=(synchronized_value const&)`]
+
+ synchronized_value& operator=(synchronized_value const& rhs);
+
+[variablelist
+
+[[Requires:] [`T` is `Assignale`.]]
+[[Effects:] [Copies the underlying value on a scope protected by the two mutexes. The mutex is not copied. The locks are acquired avoiding deadlock. For example, there is no problem if one thread assigns `a = b` and the other assigns `b = a`.]]
+[[Return:] [`*this`]]
+
+[[Throws:] [Any exception thrown by `value_type& operator(value_type const&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+[section:assign_vt `operator=(T const&)`]
+
+ synchronized_value& operator=(value_type const& val);
+
+[variablelist
+
+[[Requires:] [`T` is `Assignale`.]]
+[[Effects:] [Copies the value on a scope protected by the mutex.]]
+[[Return:] [`*this`]]
+
+[[Throws:] [Any exception thrown by `value_type& operator(value_type const&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+[section:get `get() const`]
+
+ T get() const;
+
+[variablelist
+
+[[Requires:] [`T` is `CopyConstructible`.]]
+[[Return:] [`A copy of the protected value obtained on a scope protected by the mutex.`]]
+
+[[Throws:] [Any exception thrown by `value_type(value_type const&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+
+[section:T `operator T() const`]
+
+ #if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ explicit operator T() const;
+ #endif
+
+[variablelist
+
+[[Requires:] [`T` is `CopyConstructible`.]]
+[[Return:] [`A copy of the protected value obtained on a scope protected by the mutex.`]]
+
+[[Throws:] [Any exception thrown by `value_type(value_type const&)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+[section:swap `swap(synchronized_value&)`]
+
+ void swap(synchronized_value & rhs);
+
+[variablelist
+
+[[Requires:] [`T` is `Assignale`.]]
+[[Effects:] [Swaps the data on a scope protected by both mutex. Both mutex are acquired to avoid dead-lock. The mutexes are not swapped.]]
+
+[[Throws:] [Any exception thrown by `swap(value_, rhs.value)` or `mtx_.lock()` or `rhs_.mtx_.lock()`.]]
+
+]
+
+[endsect]
+
+[section:swap_vt `swap(synchronized_value&)`]
+
+ void swap(value_type & rhs);
+
+[variablelist
+
+[[Requires:] [`T` is `Swapable`.]]
+[[Effects:] [Swaps the data on a scope protected by both mutex. Both mutex are acquired to avoid dead-lock. The mutexes are not swapped.]]
+
+[[Throws:] [Any exception thrown by `swap(value_, rhs)` or `mtx_.lock()`.]]
+
+]
+
+[endsect]
+[section:indir `operator->()`]
+
+ strict_lock_ptr<T,Lockable> operator->();
+
+
+Essentially calling a method `obj->foo(x, y, z)` calls the method `foo(x, y, z)` inside a critical section as long-lived as the call itself.
+
+[variablelist
+
+[[Return:] [`A strict_lock_ptr<>.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+[section:indir_const `operator->() const`]
+
+ const_strict_lock_ptr<T,Lockable> operator->() const;
+
+
+If the `synchronized_value` object involved is const-qualified, then you'll only be able to call const methods
+through `operator->`. So, for example, `vec->push_back("xyz")` won't work if `vec` were const-qualified.
+The locking mechanism capitalizes on the assumption that const methods don't modify their underlying data.
+
+[variablelist
+
+[[Return:] [`A const_strict_lock_ptr <>.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+[section:synchronize `synchronize()`]
+
+ strict_lock_ptr<T,Lockable> synchronize();
+
+The synchronize() factory make easier to lock on a scope. As discussed, `operator->` can only lock over the duration of a call, so it is insufficient for complex operations. With `synchronize()` you get to lock the object in a scoped and to directly access the object inside that scope.
+
+[*Example:]
+
+ void fun(synchronized_value<vector<int>> & vec) {
+ auto vec2=vec.synchronize();
+ vec2.push_back(42);
+ assert(vec2.back() == 42);
+ }
+
+[variablelist
+
+[[Return:] [`A strict_lock_ptr <>.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+[section:synchronize_const `synchronize() const`]
+
+ const_strict_lock_ptr<T,Lockable> synchronize() const;
+
+[variablelist
+
+[[Return:] [`A const_strict_lock_ptr <>.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+[section:deref `operator*()`]
+
+ deref_value operator*();;
+
+[variablelist
+
+[[Return:] [`A an instance of a class that locks the mutex on construction and unlocks it on destruction and provides implicit conversion to a reference to the protected value.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+[section:deref_const `operator*() const`]
+
+ const_deref_value operator*() const;
+
+
+[variablelist
+
+[[Return:] [`A an instance of a class that locks the mutex on construction and unlocks it on destruction and provides implicit conversion to a constant reference to the protected value.`]]
+
+[[Throws:] [Nothing.]]
+
+]
+
+[endsect]
+
+
+
+
+[endsect]
+[section:synchronize Non-Member Function `synchronize`]
+
+ #include <boost/thread/synchronized_value.hpp>
+ namespace boost
+ {
+ #if ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+ template <typename ...SV>
+ std::tuple<typename synchronized_value_strict_lock_ptr<SV>::type ...> synchronize(SV& ...sv);
+ #endif
+ }
+
+[endsect]
+[endsect]

Modified: branches/release/libs/thread/doc/once.qbk
==============================================================================
--- branches/release/libs/thread/doc/once.qbk (original)
+++ branches/release/libs/thread/doc/once.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -12,8 +12,8 @@
   namespace boost
   {
     struct once_flag;
- template<typename Callable>
- void call_once(once_flag& flag,Callable func);
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, Function&& f, ArgTypes&&... args);
 
   #if defined BOOST_THREAD_PROVIDES_DEPRECATED_FEATURES_SINCE_V3_0_0
     void call_once(void (*func)(),once_flag& flag);
@@ -45,24 +45,22 @@
 
 [section:call_once Non-member function `call_once`]
 
- template<typename Callable>
- void call_once(once_flag& flag,Callable func);
+ template<typename Function, class ...ArgTypes>
+ inline void call_once(once_flag& flag, Function&& f, ArgTypes&&... args);
 
 [variablelist
 
-[[Requires:] [`Callable` is `CopyConstructible`. Copying `func` shall have no side effects, and the effect of calling the copy shall
-be equivalent to calling the original. ]]
+[[Requires:] [`Function` and each or the `ArgTypes` are `MoveConstructible` and `invoke(decay_copy(boost::forward<Function>(f)), decay_copy(boost::forward<ArgTypes>(args))...)` shall be well formed. ]]
 
 [[Effects:] [Calls to `call_once` on the same `once_flag` object are serialized. If there has been no prior effective `call_once` on
-the same `once_flag` object, the argument `func` (or a copy thereof) is called as-if by invoking `func()`, and the invocation of
-`call_once` is effective if and only if `func()` returns without exception. If an exception is thrown, the exception is
-propagated to the caller. If there has been a prior effective `call_once` on the same `once_flag` object, the `call_once` returns
+the same `once_flag` object, the argument `func` is called as-if by invoking `invoke(decay_copy(boost::forward<Function>(f)), decay_copy(boost::forward<ArgTypes>(args))...)`, and the invocation of
+`call_once` is effective if and only if `invoke(decay_copy(boost::forward<Function>(f)), decay_copy(boost::forward<ArgTypes>(args))...)` returns without exception. If an exception is thrown, the exception is propagated to the caller. If there has been a prior effective `call_once` on the same `once_flag` object, the `call_once` returns
 without invoking `func`. ]]
 
 [[Synchronization:] [The completion of an effective `call_once` invocation on a `once_flag` object, synchronizes with
 all subsequent `call_once` invocations on the same `once_flag` object. ]]
 
-[[Throws:] [`thread_resource_error` when the effects cannot be achieved. or any exception propagated from `func`.]]
+[[Throws:] [`thread_resource_error` when the effects cannot be achieved or any exception propagated from `func`.]]
 
 [[Note:] [The function passed to `call_once` must not also call
 `call_once` passing the same `once_flag` object. This may cause
@@ -77,7 +75,7 @@
 
     void call_once(void (*func)(),once_flag& flag);
     
-This second overload is provided for backwards compatibility. The effects of `call_once(func,flag)` shall be the same as those of
+This second overload is provided for backwards compatibility and is deprecated. The effects of `call_once(func,flag)` shall be the same as those of
 `call_once(flag,func)`.
 
 [endsect]

Modified: branches/release/libs/thread/doc/sync_tutorial.qbk
==============================================================================
--- branches/release/libs/thread/doc/sync_tutorial.qbk (original)
+++ branches/release/libs/thread/doc/sync_tutorial.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -18,6 +18,8 @@
 
 [include external_locking.qbk]
 
+[include synchronized_value.qbk]
+
 [section:with Executing Around a Function]
 
 In particular, the library provides some lock factories.

Modified: branches/release/libs/thread/doc/thread.qbk
==============================================================================
--- branches/release/libs/thread/doc/thread.qbk (original)
+++ branches/release/libs/thread/doc/thread.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -235,6 +235,7 @@
 [include sync_tutorial.qbk]
 [include mutex_concepts.qbk]
 [include mutexes.qbk]
+[/include synchronized_value_ref.qbk]
 [include condition_variables.qbk]
 [include once.qbk]
 [include barrier.qbk]

Modified: branches/release/libs/thread/doc/thread_ref.qbk
==============================================================================
--- branches/release/libs/thread/doc/thread_ref.qbk (original)
+++ branches/release/libs/thread/doc/thread_ref.qbk 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -201,7 +201,7 @@
 
 [endsect]
 
-[section:detac Detaching thread]
+[section:detach Detaching thread]
 
 A thread can be detached by explicitly invoking the __detach__ member function on the __thread__
 object. In this case, the __thread__ object ceases to represent the now-detached thread, and instead represents __not_a_thread__.
@@ -1708,7 +1708,6 @@
 [section:threadgroup Class `thread_group` EXTENSION]
 
     #include <boost/thread/thread.hpp>
- #include <boost/thread/thread_group.hpp>
 
     class thread_group
     {

Modified: branches/release/libs/thread/example/make_future.cpp
==============================================================================
--- branches/release/libs/thread/example/make_future.cpp (original)
+++ branches/release/libs/thread/example/make_future.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -10,6 +10,15 @@
 
 int p1() { return 5; }
 
+void p() { }
+
+#if defined BOOST_THREAD_USES_MOVE
+boost::future<void> void_compute()
+{
+ return BOOST_THREAD_MAKE_RV_REF(boost::make_future());
+}
+#endif
+
 boost::future<int> compute(int x)
 {
   if (x == 0) return boost::make_future(0);
@@ -30,11 +39,21 @@
 
 int main()
 {
+#if defined BOOST_THREAD_USES_MOVE
+ {
+ boost::future<void> f = void_compute();
+ f.get();
+ }
+#endif
   {
     boost::future<int> f = compute(2);
     std::cout << f.get() << std::endl;
   }
   {
+ boost::future<int> f = compute(0);
+ std::cout << f.get() << std::endl;
+ }
+ {
     boost::shared_future<int> f = shared_compute(2);
     std::cout << f.get() << std::endl;
   }

Modified: branches/release/libs/thread/example/synchronized_person.cpp
==============================================================================
--- branches/release/libs/thread/example/synchronized_person.cpp (original)
+++ branches/release/libs/thread/example/synchronized_person.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -255,5 +255,28 @@
     lk2->SetName("Javier");
     lk3->SetName("Matias");
   }
+#if ! defined BOOST_NO_CXX11_AUTO_DECLARATIONS \
+&& ! defined(BOOST_THREAD_NO_SYNCHRONIZE)
+ {
+ Person3_ts p1(1);
+ Person3_ts p2(2);
+ Person3_ts p3(3);
+
+ auto t = boost::synchronize(p1,p2,p3);
+ std::get<0>(t)->SetName("Carmen");
+ std::get<1>(t)->SetName("Javier");
+ std::get<2>(t)->SetName("Matias");
+ }
+ {
+ const Person3_ts p1(1);
+ Person3_ts p2(2);
+ const Person3_ts p3(3);
+
+ auto t = boost::synchronize(p1,p2,p3);
+ //std::get<0>(t)->SetName("Carmen");
+ std::get<1>(t)->SetName("Javier");
+ //std::get<2>(t)->SetName("Matias");
+ }
+#endif
   return 0;
 }

Modified: branches/release/libs/thread/example/synchronized_value.cpp
==============================================================================
--- branches/release/libs/thread/example/synchronized_value.cpp (original)
+++ branches/release/libs/thread/example/synchronized_value.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -10,15 +10,15 @@
 #include <string>
 #include <boost/thread/synchronized_value.hpp>
 
-void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
-{
- boost::strict_lock_ptr<std::string> u=path.synchronize();
-
- if(u->empty() || (*u->rbegin()!='/'))
+ void addTrailingSlashIfMissing(boost::synchronized_value<std::string> & path)
   {
- *u+='/';
+ boost::strict_lock_ptr<std::string> u=path.synchronize();
+
+ if(u->empty() || (*u->rbegin()!='/'))
+ {
+ *u+='/';
+ }
   }
-}
 
 void f(const boost::synchronized_value<int> &v) {
   std::cout<<"v="<<*v<<std::endl;
@@ -80,6 +80,68 @@
     addTrailingSlashIfMissing(s);
     std::cout<<"s="<<std::string(*s)<<std::endl;
   }
+ {
+ boost::synchronized_value<std::string> s;
+ s = std::string("foo/");
+ std::cout<<"ss="<< s << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s;
+ s = "foo/";
+ std::cout<<"ss="<< s << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s1("a");
+ boost::synchronized_value<std::string> s2;
+ s2=s1;
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ }
+ {
+ boost::synchronized_value<std::string> s1("a");
+ boost::synchronized_value<std::string> s2("b");
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ swap(s1,s2);
+ std::cout<<"s1="<< s1 << std::endl;
+ std::cout<<"s2="<< s2 << std::endl;
+ }
+#if ! defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
+ {
+ boost::synchronized_value<std::string> sts("a");
+ std::string s(sts);
+ std::cout<<"ssts="<< s << std::endl;
+ }
+#endif
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(1);
+ BOOST_ASSERT(s1==s2);
+ BOOST_ASSERT(s1<=s2);
+ BOOST_ASSERT(s1>=s2);
+ BOOST_ASSERT(s1==1);
+ BOOST_ASSERT(s1<=1);
+ BOOST_ASSERT(s1>=1);
+ }
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(2);
+ BOOST_ASSERT(s1!=s2);
+ BOOST_ASSERT(s1!=2);
+ BOOST_ASSERT(2!=s1);
+ }
+ {
+ boost::synchronized_value<int> s1(1);
+ boost::synchronized_value<int> s2(2);
+ BOOST_ASSERT(s1<s2);
+ BOOST_ASSERT(s1<=s2);
+ BOOST_ASSERT(s2>s1);
+ BOOST_ASSERT(s2>=s1);
+ BOOST_ASSERT(s1<2);
+ BOOST_ASSERT(s1<=2);
+ BOOST_ASSERT(s2>1);
+ BOOST_ASSERT(s2>=1);
+ }
   return 0;
 }
 

Modified: branches/release/libs/thread/src/future.cpp
==============================================================================
--- branches/release/libs/thread/src/future.cpp (original)
+++ branches/release/libs/thread/src/future.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -48,13 +48,13 @@
         }
         return std::string("unspecified future_errc value\n");
     }
+ future_error_category future_error_category_var;
   }
 
   const system::error_category&
   future_category() BOOST_NOEXCEPT
   {
- static thread_detail::future_error_category f;
- return f;
+ return thread_detail::future_error_category_var;
   }
 
 }

Modified: branches/release/libs/thread/src/pthread/once_atomic.cpp
==============================================================================
--- branches/release/libs/thread/src/pthread/once_atomic.cpp (original)
+++ branches/release/libs/thread/src/pthread/once_atomic.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -4,7 +4,7 @@
 // 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)
 
-#define __STDC_CONSTANT_MACROS
+//#define __STDC_CONSTANT_MACROS
 #include <boost/thread/detail/config.hpp>
 #include <boost/thread/once.hpp>
 #include <boost/thread/pthread/pthread_mutex_scoped_lock.hpp>
@@ -24,34 +24,17 @@
       uninitialized, in_progress, initialized
     };
 
-#if BOOST_ATOMIC_INT_LOCK_FREE == 2
- typedef unsigned int atomic_int_type;
-#elif BOOST_ATOMIC_SHORT_LOCK_FREE == 2
- typedef unsigned short atomic_int_type;
-#elif BOOST_ATOMIC_CHAR_LOCK_FREE == 2
- typedef unsigned char atomic_int_type;
-#elif BOOST_ATOMIC_LONG_LOCK_FREE == 2
- typedef unsigned long atomic_int_type;
-#elif defined(BOOST_HAS_LONG_LONG) && BOOST_ATOMIC_LLONG_LOCK_FREE == 2
- typedef ulong_long_type atomic_int_type;
-#else
- // All tested integer types are not atomic, the spinlock pool will be used
- typedef unsigned int atomic_int_type;
-#endif
 
- typedef boost::atomic<atomic_int_type> atomic_type
- //#if defined(__GNUC__)
- // __attribute__((may_alias))
- //#endif
- ;
- BOOST_STATIC_ASSERT_MSG(sizeof(once_flag) >= sizeof(atomic_type), "Boost.Thread: unsupported platform");
+#ifndef BOOST_THREAD_PROVIDES_ONCE_CXX11
+ BOOST_STATIC_ASSERT_MSG(sizeof(atomic_int_type) == sizeof(atomic_type), "Boost.Thread: unsupported platform");
+#endif
 
     static pthread_mutex_t once_mutex = PTHREAD_MUTEX_INITIALIZER;
     static pthread_cond_t once_cv = PTHREAD_COND_INITIALIZER;
 
     BOOST_THREAD_DECL bool enter_once_region(once_flag& flag) BOOST_NOEXCEPT
     {
- atomic_type& f = reinterpret_cast< atomic_type& >(flag.storage);
+ atomic_type& f = get_atomic_storage(flag);
       if (f.load(memory_order_acquire) != initialized)
       {
         pthread::pthread_mutex_scoped_lock lk(&once_mutex);
@@ -84,7 +67,7 @@
 
     BOOST_THREAD_DECL void commit_once_region(once_flag& flag) BOOST_NOEXCEPT
     {
- atomic_type& f = reinterpret_cast< atomic_type& >(flag.storage);
+ atomic_type& f = get_atomic_storage(flag);
       {
         pthread::pthread_mutex_scoped_lock lk(&once_mutex);
         f.store(initialized, memory_order_release);
@@ -94,7 +77,7 @@
 
     BOOST_THREAD_DECL void rollback_once_region(once_flag& flag) BOOST_NOEXCEPT
     {
- atomic_type& f = reinterpret_cast< atomic_type& >(flag.storage);
+ atomic_type& f = get_atomic_storage(flag);
       {
         pthread::pthread_mutex_scoped_lock lk(&once_mutex);
         f.store(uninitialized, memory_order_release);

Modified: branches/release/libs/thread/src/win32/thread.cpp
==============================================================================
--- branches/release/libs/thread/src/win32/thread.cpp (original)
+++ branches/release/libs/thread/src/win32/thread.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -402,7 +402,8 @@
 
     unsigned thread::hardware_concurrency() BOOST_NOEXCEPT
     {
- SYSTEM_INFO info={{0}};
+ //SYSTEM_INFO info={{0}};
+ SYSTEM_INFO info;
         GetSystemInfo(&info);
         return info.dwNumberOfProcessors;
     }
@@ -425,7 +426,7 @@
         {
             LARGE_INTEGER get_due_time(detail::timeout const& target_time)
             {
- LARGE_INTEGER due_time={{0}};
+ LARGE_INTEGER due_time={{0,0}};
                 if(target_time.relative)
                 {
                     unsigned long const elapsed_milliseconds=GetTickCount()-target_time.start;
@@ -439,7 +440,7 @@
                 }
                 else
                 {
- SYSTEMTIME target_system_time={0};
+ SYSTEMTIME target_system_time={0,0,0,0,0,0,0,0};
                     target_system_time.wYear=target_time.abs_time.date().year();
                     target_system_time.wMonth=target_time.abs_time.date().month();
                     target_system_time.wDay=target_time.abs_time.date().day();
@@ -748,4 +749,3 @@
     }
 }
 
-

Modified: branches/release/libs/thread/test/Jamfile.v2
==============================================================================
--- branches/release/libs/thread/test/Jamfile.v2 (original)
+++ branches/release/libs/thread/test/Jamfile.v2 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -31,12 +31,18 @@
         <toolset>gcc:<cxxflags>-Wno-long-long
         #<toolset>gcc:<cxxflags>-ansi
         #<toolset>gcc:<cxxflags>-fpermissive
+ <toolset>gcc:<cxxflags>-Wno-variadic-macros
+ #<toolset>gcc:<cxxflags>-Wunused-local-typedefs
+ <toolset>gcc:<cxxflags>-Wunused-function
 
         <toolset>darwin:<cxxflags>-Wextra
         <toolset>darwin:<cxxflags>-pedantic
         <toolset>darwin:<cxxflags>-Wno-long-long
         #<toolset>darwin:<cxxflags>-ansi # doesn't work for 4.1.2
         <toolset>darwin:<cxxflags>-fpermissive
+ <toolset>darwin:<cxxflags>-Wno-variadic-macros
+ #<toolset>darwin:<cxxflags>-Wunused-local-typedefs
+ <toolset>darwin:<cxxflags>-Wunused-function
 
         #<toolset>pathscale:<cxxflags>-Wextra
         <toolset>pathscale:<cxxflags>-Wno-long-long
@@ -47,6 +53,7 @@
         <toolset>clang:<cxxflags>-Wno-long-long
         #<toolset>clang:<cxxflags>-ansi
         #<toolset>clang:<cxxflags>-fpermissive # doesn't work
+ <toolset>clang:<cxxflags>-Wunused-function
 
         <toolset>gcc-mingw-4.4.0:<cxxflags>-fdiagnostics-show-option
         <toolset>gcc-mingw-4.5.0:<cxxflags>-fdiagnostics-show-option
@@ -127,7 +134,7 @@
         : : :
       : $(name)_lib ]
     #[ run $(sources) ../build//boost_thread : : :
- # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
     # : $(name)_noit ]
     ;
 }
@@ -141,7 +148,7 @@
         : : : <threadapi>win32:<build>no
       : $(name)_lib ]
     #[ run $(sources) ../build//boost_thread : : :
- # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ # <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
     # : $(name)_noit ]
     ;
 }
@@ -149,10 +156,10 @@
 rule thread-run2-h ( sources : name )
 {
     return
- [ run $(sources) : : :
+ [ run $(sources) : : :
       <library>/boost/system//boost_system
- <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
- <define>BOOST_THREAD_VERSION=3
+ <define>BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
+ <define>BOOST_THREAD_VERSION=3
     : $(name)_h ]
     ;
 }
@@ -695,6 +702,26 @@
           [ thread-run2-noit ./sync/mutual_exclusion/locks/reverse_lock/types_pass.cpp : reverse_lock__types_p ]
     ;
 
+
+ #explicit ts_synchronized_value ;
+ test-suite ts_synchronized_value
+ :
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_assign_pass.cpp : synchronized_value__copy_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_ctor_pass.cpp : synchronized_value__copy_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_T_assign_pass.cpp : synchronized_value__copy_T_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/copy_T_ctor_pass.cpp : synchronized_value__copy_T_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/default_ctor_pass.cpp : synchronized_value__default_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/indirect_pass.cpp : synchronized_value__indirect_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_assign_pass.cpp : synchronized_value__move_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_ctor_pass.cpp : synchronized_value__move_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_T_assign_pass.cpp : synchronized_value__move_T_assign_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/move_T_ctor_pass.cpp : synchronized_value__move_T_ctor_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_pass.cpp : synchronized_value__swap_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/swap_T_pass.cpp : synchronized_value__swap_T_p ]
+ [ thread-run2-noit ./sync/mutual_exclusion/synchronized_value/synchronize_pass.cpp : synchronized_value__synchronize_p ]
+
+ ;
+
     explicit ts_ ;
     test-suite ts_
     :
@@ -703,11 +730,14 @@
           #[ thread-run ../example/test_so2.cpp ]
 
           #[ compile virtual_noexcept.cpp ]
- #[ thread-run test_7665.cpp ]
+ #[ thread-run test_7720.cpp ]
           #[ thread-run test_7666.cpp ]
+ #[ thread-run test_7755.cpp ]
           #[ thread-run ../example/unwrap.cpp ]
- [ thread-run ../example/perf_condition_variable.cpp ]
+ #[ thread-run ../example/perf_condition_variable.cpp ]
+ #[ thread-run ../example/perf_shared_mutex.cpp ]
           #[ thread-run ../example/not_interleaved.cpp ]
+
     ;
 
 }

Modified: branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/packaged_task/make_ready_at_thread_exit_pass.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -57,12 +57,17 @@
   }
 };
 
+void func0_mv(BOOST_THREAD_RV_REF(boost::packaged_task<double(int, char)>) p)
+//void func0(boost::packaged_task<double(int, char)> p)
+{
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ p.make_ready_at_thread_exit(3, 'a');
+}
 void func0(boost::packaged_task<double(int, char)> *p)
 {
   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
   p->make_ready_at_thread_exit(3, 'a');
 }
-
 void func1(boost::packaged_task<double(int, char)> *p)
 {
   boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
@@ -99,8 +104,11 @@
   {
     boost::packaged_task<double(int, char)> p(A(5));
     boost::future<double> f = p.get_future();
- // fixme BUG boost::thread(func0, boost::move(p)).detach();
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ boost::thread(func0_mv, boost::move(p)).detach();
+#else
     boost::thread(func0, &p).detach();
+#endif
     BOOST_TEST(f.get() == 105.0);
   }
   {

Modified: branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/promise/set_value_at_thread_exit_void_pass.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -19,11 +19,8 @@
 // void promise<void>::set_value_at_thread_exit();
 
 #define BOOST_THREAD_VERSION 4
-#define BOOST_THREAD_USES_LOG
-#define BOOST_THREAD_USES_LOG_THREAD_ID
 
 #include <boost/thread/future.hpp>
-#include <boost/thread/detail/log.hpp>
 #include <boost/detail/lightweight_test.hpp>
 
 int i = 0;
@@ -35,12 +32,17 @@
   i = 1;
 }
 
-void func2(boost::promise<void> p2)
+void func2_mv(BOOST_THREAD_RV_REF(boost::promise<void>) p2)
 {
   p2.set_value_at_thread_exit();
   i = 2;
 }
 
+void func2(boost::promise<void> *p2)
+{
+ p2->set_value_at_thread_exit();
+ i = 2;
+}
 int main()
 {
   try
@@ -51,7 +53,7 @@
     BOOST_TEST(i == 1);
 
   }
- catch(std::exception ex)
+ catch(std::exception& ex)
   {
     BOOST_TEST(false);
   }
@@ -70,7 +72,29 @@
     BOOST_TEST(i == 1);
 
   }
- catch(std::exception ex)
+ catch(std::exception& ex)
+ {
+ std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
+ BOOST_TEST(false);
+ }
+ catch(...)
+ {
+ BOOST_TEST(false);
+ }
+
+ try
+ {
+ boost::promise<void> p2;
+ boost::future<void> f = p2.get_future();
+#if defined BOOST_THREAD_PROVIDES_VARIADIC_THREAD
+ boost::thread(func2_mv, boost::move(p2)).detach();
+#else
+ boost::thread(func2, &p2).detach();
+#endif
+ f.wait();
+ BOOST_TEST(i == 2);
+ }
+ catch(std::exception& ex)
   {
     std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
     BOOST_TEST(false);
@@ -79,31 +103,6 @@
   {
     BOOST_TEST(false);
   }
- // BUG when moving promise. fixme
-// try
-// {
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-// boost::promise<void> p2; // BUG
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-// boost::future<void> f = p2.get_future();
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-// boost::thread(func2, boost::move(p2)).detach(); // BUG
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-// f.get();
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-// BOOST_TEST(i == 2);
-// BOOST_THREAD_LOG << BOOST_THREAD_END_LOG
-//
-// }
-// catch(std::exception ex)
-// {
-// std::cout << __FILE__ << ":" << __LINE__ << " " << ex.what() << std::endl;
-// BOOST_TEST(false);
-// }
-// catch(...)
-// {
-// BOOST_TEST(false);
-// }
   return boost::report_errors();
 }
 

Modified: branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/mutual_exclusion/once/call_once/call_once_pass.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -109,11 +109,11 @@
 void f1_member()
 {
     init1_member o;
-#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
+//#if defined BOOST_THREAD_PROVIDES_ONCE_CXX11
     boost::call_once(flg1_member, &init1_member::call, o, 1);
-#else
- boost::call_once(flg1_member, boost::bind(&init1_member::call, o, 1));
-#endif
+//#else
+// boost::call_once(flg1_member, boost::bind(&init1_member::call, boost::ref(o), 1));
+//#endif
 }
 //#endif
 struct init2
@@ -248,12 +248,12 @@
         boost::once_flag f BOOST_INIT_ONCE_INIT;
         boost::call_once(f, MoveOnly());
     }
+#endif
+#if defined BOOST_THREAD_PROVIDES_INVOKE
     {
         boost::once_flag f BOOST_INIT_ONCE_INIT;
         boost::call_once(f, MoveOnly(), 1);
     }
-#endif
-#if defined BOOST_THREAD_PROVIDES_INVOKE
     {
         boost::once_flag f BOOST_INIT_ONCE_INIT;
         boost::call_once(f, MoveOnly(), MoveOnly());

Modified: branches/release/libs/thread/test/test_barrier.cpp
==============================================================================
--- branches/release/libs/thread/test/test_barrier.cpp (original)
+++ branches/release/libs/thread/test/test_barrier.cpp 2013-03-22 21:48:21 EDT (Fri, 22 Mar 2013)
@@ -11,7 +11,8 @@
 #include <boost/thread/thread.hpp>
 #include <boost/thread/barrier.hpp>
 
-#include <boost/test/unit_test.hpp>
+#include <boost/detail/lightweight_test.hpp>
+//#include <boost/test/unit_test.hpp>
 #include <vector>
 
 namespace {
@@ -54,16 +55,21 @@
         throw;
     }
 
- BOOST_CHECK_EQUAL(global_parameter,5);
+ //BOOST_CHECK_EQUAL(global_parameter,5);
+ BOOST_TEST(global_parameter==5);
+
 }
 
-boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+//boost::unit_test::test_suite* init_unit_test_suite(int, char*[])
+int main()
 {
- boost::unit_test::test_suite* test =
- BOOST_TEST_SUITE("Boost.Threads: barrier test suite");
-
- test->add(BOOST_TEST_CASE(&test_barrier));
-
- return test;
+// boost::unit_test::test_suite* test =
+// BOOST_TEST_SUITE("Boost.Threads: barrier test suite");
+//
+// test->add(BOOST_TEST_CASE(&test_barrier));
+
+ test_barrier();
+ return boost::report_errors();
+ //return test;
 }
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk