Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84468 - in branches/release: boost/thread boost/thread/detail libs/thread libs/thread/test/sync/futures/packaged_task
From: vicente.botet_at_[hidden]
Date: 2013-05-24 17:27:54


Author: viboes
Date: 2013-05-24 17:27:53 EDT (Fri, 24 May 2013)
New Revision: 84468
URL: http://svn.boost.org/trac/boost/changeset/84468

Log:
Thread: merge 84414 to fix #8596.
Properties modified:
   branches/release/boost/thread/ (props changed)
   branches/release/libs/thread/ (props changed)
Text files modified:
   branches/release/boost/thread/detail/config.hpp | 6
   branches/release/boost/thread/future.hpp | 77 ++++++++----------
   branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp | 161 +++++++++++++++++++++++++++++++++++++--
   3 files changed, 187 insertions(+), 57 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-05-24 17:27:53 EDT (Fri, 24 May 2013)
@@ -13,8 +13,6 @@
 #include <boost/thread/detail/platform.hpp>
 
 //#define BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS
-
-
 // ATTRIBUTE_MAY_ALIAS
 
 #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) > 302 \
@@ -95,9 +93,9 @@
 #endif
 
 /// RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
-#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
+//#if defined BOOST_NO_CXX11_RVALUE_REFERENCES || defined BOOST_MSVC
 #define BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
-#endif
+//#endif
 
 // Default version
 #if !defined BOOST_THREAD_VERSION

Modified: branches/release/boost/thread/future.hpp
==============================================================================
--- branches/release/boost/thread/future.hpp (original)
+++ branches/release/boost/thread/future.hpp 2013-05-24 17:27:53 EDT (Fri, 24 May 2013)
@@ -2275,18 +2275,12 @@
           task_object(task_object&);
         public:
             F f;
-#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
- task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::forward<F>(f_))
- {}
-#else
             task_object(F const& f_):
                 f(f_)
             {}
             task_object(BOOST_THREAD_RV_REF(F) f_):
- f(boost::move(f_)) // TODO forward
+ f(boost::move(f_))
             {}
-#endif
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
             void do_apply(BOOST_THREAD_RV_REF(ArgTypes) ... args)
@@ -2837,12 +2831,11 @@
 #endif
 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
         template <class F>
- explicit packaged_task(BOOST_THREAD_RV_REF(F) f
+ explicit packaged_task(BOOST_THREAD_FWD_REF(F) f
             , typename disable_if<is_same<typename decay<F>::type, packaged_task>, dummy* >::type=0
             )
         {
- //typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
- typedef F FR;
+ typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
             typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
@@ -2921,10 +2914,9 @@
 
 #if ! defined BOOST_NO_CXX11_RVALUE_REFERENCES
         template <class F, class Allocator>
- packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_RV_REF(F) f)
+ packaged_task(boost::allocator_arg_t, Allocator a, BOOST_THREAD_FWD_REF(F) f)
         {
- //typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
- typedef F FR;
+ typedef typename remove_cv<typename remove_reference<F>::type>::type FR;
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
   #if defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
           typedef detail::task_object<FR,R(ArgTypes...)> task_object_type;
@@ -3150,11 +3142,6 @@
     // future<R> async(launch policy, F&&, ArgTypes&&...);
     ////////////////////////////////
 
- ////////////////////////////////
- // template <class F, class... ArgTypes>
- // future<R> async(F&&, ArgTypes&&...);
- ////////////////////////////////
-
 #if defined BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -3163,8 +3150,9 @@
         BOOST_THREAD_FUTURE<R>
         async(launch policy, R(*f)(BOOST_THREAD_FWD_REF(ArgTypes)...), BOOST_THREAD_FWD_REF(ArgTypes)... args)
         {
- //typedef packaged_task<R(BOOST_THREAD_FWD_REF(ArgTypes)...)> packaged_task_type;
- typedef packaged_task<R(ArgTypes...)> packaged_task_type;
+ typedef R(*F)(BOOST_THREAD_FWD_REF(ArgTypes)...);
+ typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
+ typedef typename BF::result_type Rp;
   #else
         template <class R>
         BOOST_THREAD_FUTURE<R>
@@ -3181,37 +3169,44 @@
 #endif
           if (int(policy) & int(launch::async))
             {
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ 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( f );
 
               BOOST_THREAD_FUTURE<R> ret = BOOST_THREAD_MAKE_RV_REF(pt.get_future());
               ret.set_async();
-#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach();
-#else
               boost::thread( boost::move(pt) ).detach();
-#endif
               return ::boost::move(ret);
+#endif
             }
             else if (int(policy) & int(launch::deferred))
             {
- packaged_task_type pt( f );
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ 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
+ std::terminate();
+ BOOST_THREAD_FUTURE<R> ret;
+ return ::boost::move(ret);
 
- BOOST_THREAD_FUTURE<R> ret = pt.get_future();
- ret.set_deferred();
- return ::boost::move(ret);
+#endif
             } else {
- //BOOST_THREAD_LOG << "ERROR async "<< int(policy) << BOOST_THREAD_END_LOG;
+ std::terminate();
               BOOST_THREAD_FUTURE<R> ret;
               return ::boost::move(ret);
             }
         }
 
-// template <class R>
-// BOOST_THREAD_FUTURE<R>
-// async(R(*f)())
-// {
-// return BOOST_THREAD_MAKE_RV_REF(async(launch(launch::any), f));
-// }
 #endif
 
 #if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
@@ -3227,7 +3222,6 @@
           typedef typename boost::result_of<typename decay<F>::type(
               typename decay<ArgTypes>::type...
           )>::type R;
- typedef packaged_task<R(ArgTypes...)> packaged_task_type;
 
           typedef detail::async_func<typename decay<F>::type, typename decay<ArgTypes>::type...> BF;
           typedef typename BF::result_type Rp;
@@ -3265,11 +3259,11 @@
 
           BOOST_THREAD_FUTURE<R> ret = pt.get_future();
           ret.set_async();
-#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
- boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach(); // todo forward
-#else
+//#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+// boost::thread( boost::move(pt), boost::forward<ArgTypes>(args)... ).detach(); // todo forward
+//#else
           boost::thread( boost::move(pt) ).detach();
-#endif
+//#endif
           return ::boost::move(ret);
 #endif
         }
@@ -3283,6 +3277,7 @@
               )
           ));
 #else
+ std::terminate();
               BOOST_THREAD_FUTURE<R> ret;
               return ::boost::move(ret);
 // return boost::detail::make_future_deferred_object<Rp>(
@@ -3293,7 +3288,7 @@
 #endif
 
         } else {
- //BOOST_THREAD_LOG << "ERROR async "<< int(policy) << BOOST_THREAD_END_LOG;
+ std::terminate();
           BOOST_THREAD_FUTURE<R> ret;
           return ::boost::move(ret);
         }

Modified: branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp
==============================================================================
--- branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp (original)
+++ branches/release/libs/thread/test/sync/futures/packaged_task/func_ctor_pass.cpp 2013-05-24 17:27:53 EDT (Fri, 24 May 2013)
@@ -54,24 +54,43 @@
 
 class A
 {
+public:
   long data_;
 
-public:
- BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
   static int n_moves;
   static int n_copies;
+ BOOST_THREAD_COPYABLE_AND_MOVABLE(A)
+ static void reset()
+ {
+ n_moves=0;
+ n_copies=0;
+ }
 
   explicit A(long i) : data_(i)
   {
   }
   A(BOOST_THREAD_RV_REF(A) a) : data_(BOOST_THREAD_RV(a).data_)
   {
- ++n_moves; BOOST_THREAD_RV(a).data_ = -1;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ A& operator=(BOOST_THREAD_RV_REF(A) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
   }
   A(const A& a) : data_(a.data_)
   {
     ++n_copies;
   }
+ A& operator=(A const& a)
+ {
+ data_ = a.data_;
+ ++n_copies;
+ return *this;
+ }
   ~A()
   {
   }
@@ -85,6 +104,78 @@
 int A::n_moves = 0;
 int A::n_copies = 0;
 
+class M
+{
+
+public:
+ long data_;
+ static int n_moves;
+
+ BOOST_THREAD_MOVABLE_ONLY(M)
+ static void reset() {
+ n_moves=0;
+ }
+ explicit M(long i) : data_(i)
+ {
+ }
+ M(BOOST_THREAD_RV_REF(M) a) : data_(BOOST_THREAD_RV(a).data_)
+ {
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ }
+ M& operator=(BOOST_THREAD_RV_REF(M) a)
+ {
+ data_ = BOOST_THREAD_RV(a).data_;
+ BOOST_THREAD_RV(a).data_ = -1;
+ ++n_moves;
+ return *this;
+ }
+ ~M()
+ {
+ }
+
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+
+int M::n_moves = 0;
+
+class C
+{
+public:
+ long data_;
+
+ static int n_copies;
+ static void reset()
+ {
+ n_copies=0;
+ }
+
+ explicit C(long i) : data_(i)
+ {
+ }
+ C(const C& a) : data_(a.data_)
+ {
+ ++n_copies;
+ }
+ C& operator=(C const& a)
+ {
+ data_ = a.data_;
+ ++n_copies;
+ return *this;
+ }
+ ~C()
+ {
+ }
+
+ long operator()() const
+ { return data_;}
+ long operator()(long i, long j) const
+ { return data_ + i + j;}
+};
+int C::n_copies = 0;
 
 int main()
 {
@@ -99,11 +190,10 @@
 #endif
       BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
       BOOST_TEST(A::n_copies == 0);
- BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST_EQ(A::n_moves, 1);
   }
- A::n_copies = 0;
- A::n_moves = 0;
   {
+ A::reset();
       A a(5);
       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
       BOOST_TEST(p.valid());
@@ -111,13 +201,12 @@
       //p(3, 'a');
       p();
       BOOST_TEST(f.get() == 5.0);
- //BOOST_TEST(A::n_copies > 0);
- //BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
   }
 
- A::n_copies = 0;
- A::n_moves = 0;
   {
+ A::reset();
       const A a(5);
       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
       BOOST_TEST(p.valid());
@@ -125,8 +214,56 @@
       //p(3, 'a');
       p();
       BOOST_TEST(f.get() == 5.0);
- //BOOST_TEST(A::n_copies > 0);
- //BOOST_TEST(A::n_moves > 0);
+ BOOST_TEST_EQ(A::n_copies, 1);
+ BOOST_TEST_EQ(A::n_moves, 0);
+ }
+ {
+ M::reset();
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE_2> p(BOOST_THREAD_MAKE_RV_REF(M(5)));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+#if defined BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK && defined(BOOST_THREAD_PROVIDES_VARIADIC_THREAD)
+ p(3, 'a');
+#else
+ p();
+#endif
+ BOOST_TEST(f.get() == BOOST_THREAD_DETAIL_SIGNATURE_2_RES);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+ {
+ M::reset();
+ M a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(boost::move(a));
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(M::n_moves, 1);
+ }
+
+ {
+ C::reset();
+ C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(C::n_copies, 1);
+ }
+
+ {
+ C::reset();
+ const C a(5);
+ boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(a);
+ BOOST_TEST(p.valid());
+ boost::future<double> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
+ //p(3, 'a');
+ p();
+ BOOST_TEST(f.get() == 5.0);
+ BOOST_TEST_EQ(C::n_copies, 1);
   }
   {
       boost::packaged_task<BOOST_THREAD_DETAIL_SIGNATURE> p(fct);


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