Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r81291 - in trunk: boost/thread libs/thread/test libs/thread/test/sync/futures/future
From: vicente.botet_at_[hidden]
Date: 2012-11-10 20:05:56


Author: viboes
Date: 2012-11-10 20:05:55 EST (Sat, 10 Nov 2012)
New Revision: 81291
URL: http://svn.boost.org/trac/boost/changeset/81291

Log:
Thread: towards future<>::then(launch, ...
Text files modified:
   trunk/boost/thread/future.hpp | 137 +++++++++++++++++++++++++++++++++++----
   trunk/libs/thread/test/Jamfile.v2 | 3
   trunk/libs/thread/test/sync/futures/future/then_pass.cpp | 18 ++--
   3 files changed, 134 insertions(+), 24 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp (original)
+++ trunk/boost/thread/future.hpp 2012-11-10 20:05:55 EST (Sat, 10 Nov 2012)
@@ -263,7 +263,8 @@
 
             boost::exception_ptr exception;
             bool done;
- bool is_deferred;
+ bool is_deferred_;
+ launch policy_;
             bool is_constructed;
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
             bool thread_was_interrupted;
@@ -276,10 +277,10 @@
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
             shared_ptr<future_continuation_base> continuation_ptr;
 #endif
-
             future_object_base():
                 done(false),
- is_deferred(false),
+ is_deferred_(false),
+ policy_(launch::any),
                 is_constructed(false)
 #if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
                , thread_was_interrupted(false)
@@ -291,7 +292,8 @@
             virtual ~future_object_base()
             {}
 
- void set_deferred() {is_deferred = true;}
+ void set_deferred() {is_deferred_ = true;}
+ void set_launch_policy(launch policy) {policy_ = policy;}
 
             waiter_list::iterator register_external_waiter(boost::condition_variable_any& cv)
             {
@@ -360,9 +362,9 @@
               do_callback(lock);
               //if (!done) // fixme why this doesn't works?
               {
- if (is_deferred)
+ if (is_deferred_)
                 {
- is_deferred=false;
+ is_deferred_=false;
                   execute(lock);
                   //lock.unlock();
                 }
@@ -395,7 +397,7 @@
             bool timed_wait_until(boost::system_time const& target_time)
             {
                 boost::unique_lock<boost::mutex> lock(mutex);
- if (is_deferred)
+ if (is_deferred_)
                     return false;
 
                 do_callback(lock);
@@ -417,7 +419,7 @@
             wait_until(const chrono::time_point<Clock, Duration>& abs_time)
             {
               boost::unique_lock<boost::mutex> lock(mutex);
- if (is_deferred)
+ if (is_deferred_)
                   return future_status::deferred;
               do_callback(lock);
               while(!done)
@@ -503,6 +505,12 @@
 #endif
                     );
             }
+ void is_deferred() {is_deferred_ = true;}
+
+ launch launch_policy() const BOOST_NOEXCEPT
+ {
+ return policy_;
+ }
 
             template<typename F,typename U>
             void set_wait_callback(F f,U* u)
@@ -1303,6 +1311,12 @@
             return future_ && future_->has_value();
         }
 
+ launch launch_policy() const BOOST_NOEXCEPT
+ {
+ if ( future_ ) return future_->launch_policy();
+ else return launch(launch::any);
+ }
+
         bool valid() const BOOST_NOEXCEPT
         {
             return future_ != 0;
@@ -1475,9 +1489,15 @@
 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
         template<typename RF>
         inline BOOST_THREAD_FUTURE<RF> then(RF(*func)(BOOST_THREAD_FUTURE&));
+ template<typename RF>
+ inline BOOST_THREAD_FUTURE<RF> then(launch policy, RF(*func)(BOOST_THREAD_FUTURE&));
 #endif
         template<typename F>
- inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type> then(BOOST_THREAD_RV_REF(F) func);
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
+ then(BOOST_THREAD_RV_REF(F) func);
+ template<typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE&)>::type>
+ then(launch policy, BOOST_THREAD_RV_REF(F) func);
 #endif
     };
 
@@ -3044,11 +3064,19 @@
       {
         F& parent;
         C continuation;
+ launch policy_;
         promise<R> next;
 
         future_continuation(F& f, BOOST_THREAD_FWD_REF(C) c) :
           parent(f),
           continuation(boost::forward<C>(c)),
+ policy_(f.launch_policy()),
+ next()
+ {}
+ future_continuation(F& f, BOOST_THREAD_FWD_REF(C) c, launch policy) :
+ parent(f),
+ continuation(boost::forward<C>(c)),
+ policy_(policy),
           next()
         {}
         ~future_continuation()
@@ -3059,8 +3087,18 @@
           try
           {
             lk.unlock();
- R val = continuation(parent);
- next.set_value(boost::move(val));
+ // fixme what to do depending on inherits_launch_policy_ and policy_?
+// if (int(policy_) & int(launch::deferred))
+ {
+ R val = continuation(parent);
+ next.set_value(boost::move(val));
+ }
+// else
+// {
+// BOOST_THREAD_FUTURE<R> f = async(policy_, continuation, boost::ref(parent));
+// R val = f.get();
+// next.set_value(boost::move(val));
+// }
           }
           catch (...)
           {
@@ -3078,11 +3116,19 @@
       {
         F& parent;
         CR(*continuation)(F&) ;
+ launch policy_;
         promise<R> next;
 
         future_continuation(F& f, CR(*c)(F&)) :
           parent(f),
           continuation(c),
+ policy_(f.launch_policy()),
+ next()
+ {}
+ future_continuation(F& f, CR(*c)(F&), launch policy) :
+ parent(f),
+ continuation(c),
+ policy_(policy),
           next()
         {}
         ~future_continuation()
@@ -3093,8 +3139,18 @@
           try
           {
             lk.unlock();
- R val = continuation(parent);
- next.set_value(boost::move(val));
+ // fixme what to do depending on inherits_launch_policy_ and policy_?
+// if (int(policy_) & int(launch::deferred))
+ {
+ R val = continuation(parent);
+ next.set_value(boost::move(val));
+ }
+// else
+// {
+// BOOST_THREAD_FUTURE<R> f = async(policy_, continuation, boost::ref(parent));
+// R val = f.get();
+// next.set_value(boost::move(val));
+// }
           }
           catch (...)
           {
@@ -3117,6 +3173,33 @@
   template <typename R>
   template <typename F>
   inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type>
+ BOOST_THREAD_FUTURE<R>::then(launch policy, BOOST_THREAD_RV_REF(F) func)
+ {
+
+ typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
+
+ if (this->future_)
+ {
+ 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), policy);
+ if (ptr==0)
+ {
+ return 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>();
+ }
+
+ }
+ template <typename R>
+ template <typename F>
+ inline BOOST_THREAD_FUTURE<typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type>
   BOOST_THREAD_FUTURE<R>::then(BOOST_THREAD_RV_REF(F) func)
   {
 
@@ -3134,11 +3217,11 @@
       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>();
     }
 
   }
-
 #if defined(BOOST_THREAD_RVALUE_REFERENCES_DONT_MATCH_FUNTION_PTR)
   template <typename R>
   template<typename RF>
@@ -3160,6 +3243,32 @@
       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>();
+ }
+
+ }
+ template <typename R>
+ template<typename RF>
+ BOOST_THREAD_FUTURE<RF>
+ BOOST_THREAD_FUTURE<R>::then(launch policy, RF(*func)(BOOST_THREAD_FUTURE<R>&))
+ {
+
+ typedef RF future_type;
+
+ if (this->future_)
+ {
+ 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);
+ if (ptr==0)
+ {
+ return 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>();
     }
 

Modified: trunk/libs/thread/test/Jamfile.v2
==============================================================================
--- trunk/libs/thread/test/Jamfile.v2 (original)
+++ trunk/libs/thread/test/Jamfile.v2 2012-11-10 20:05:55 EST (Sat, 10 Nov 2012)
@@ -285,6 +285,7 @@
           [ thread-run2 ./sync/futures/future/move_ctor_pass.cpp : future__move_ctor_p ]
           [ thread-run2 ./sync/futures/future/move_assign_pass.cpp : future__move_asign_p ]
           [ thread-run2 ./sync/futures/future/share_pass.cpp : future__share_p ]
+ [ thread-run2 ./sync/futures/future/then_pass.cpp : future__then_p ]
     ;
 
     #explicit ts_shared_future ;
@@ -589,7 +590,7 @@
     test-suite ts_
     :
           #[ thread-run test_7665.cpp ]
- [ thread-run test_7666.cpp ]
+ #[ thread-run test_7666.cpp ]
           #[ compile ../example/tes_is_function.cpp ]
           #[ thread-run ../example/unwrap.cpp ]
     ;

Modified: trunk/libs/thread/test/sync/futures/future/then_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/then_pass.cpp (original)
+++ trunk/libs/thread/test/sync/futures/future/then_pass.cpp 2012-11-10 20:05:55 EST (Sat, 10 Nov 2012)
@@ -1,12 +1,3 @@
-//===----------------------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
 // Copyright (C) 2011 Vicente J. Botet Escriba
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -20,6 +11,7 @@
 // auto then(F&& func) -> BOOST_THREAD_FUTURE<decltype(func(*this))>;
 
 #define BOOST_THREAD_VERSION 4
+#define BOOST_THREAD_DONT_PROVIDE_FUTURE_INVALID_AFTER_GET
 
 #include <boost/thread/future.hpp>
 #include <boost/detail/lightweight_test.hpp>
@@ -44,10 +36,18 @@
     BOOST_TEST(f2.get()==2);
   }
   {
+ boost::future<int> f2 = boost::async(p1).then(p2);
+ BOOST_TEST(f2.get()==2);
+ }
+ {
     boost::future<int> f1 = boost::async(p1);
     boost::future<int> f2 = f1.then(p2).then(p2);
     BOOST_TEST(f2.get()==4);
   }
+ {
+ boost::future<int> f2 = boost::async(p1).then(p2).then(p2);
+ BOOST_TEST(f2.get()==4);
+ }
 
   return boost::report_errors();
 }


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