Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r84685 - in trunk: boost/thread libs/thread/test/sync/futures/future libs/thread/test/sync/futures/promise libs/thread/test/sync/futures/shared_future
From: vicente.botet_at_[hidden]
Date: 2013-06-08 06:53:46


Author: viboes
Date: 2013-06-08 06:53:46 EDT (Sat, 08 Jun 2013)
New Revision: 84685
URL: http://svn.boost.org/trac/boost/changeset/84685

Log:
Thread: fix bug on future::then when the continuation is void() ir T&().

Text files modified:
   trunk/boost/thread/future.hpp | 104 ++++++++++++++++++++++-----------------
   trunk/libs/thread/test/sync/futures/future/then_pass.cpp | 34 ++++++++++++
   trunk/libs/thread/test/sync/futures/promise/default_pass.cpp | 2
   trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp | 33 ++++++++++++
   4 files changed, 124 insertions(+), 49 deletions(-)

Modified: trunk/boost/thread/future.hpp
==============================================================================
--- trunk/boost/thread/future.hpp Sat Jun 8 04:21:34 2013 (r84684)
+++ trunk/boost/thread/future.hpp 2013-06-08 06:53:46 EDT (Sat, 08 Jun 2013) (r84685)
@@ -3467,7 +3467,7 @@
       Fp continuation;
 
     public:
- explicit future_async_continuation_shared_state(
+ future_async_continuation_shared_state(
           F& f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
       parent(f.future_),
@@ -3503,14 +3503,14 @@
     template<typename F, typename Fp>
     struct future_async_continuation_shared_state<F, void, Fp>: public future_async_shared_state_base<void>
     {
- F& parent;
+ F parent;
       Fp continuation;
 
     public:
- explicit future_async_continuation_shared_state(
+ future_async_continuation_shared_state(
           F& f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
- parent(f),
+ parent(f.future_),
       //continuation(boost::forward<Fp>(c)
       continuation(boost::move(c))
       {
@@ -3549,14 +3549,14 @@
     template<typename F, typename Rp, typename Fp>
     struct future_deferred_continuation_shared_state: shared_state<Rp>
     {
- F& parent;
+ F parent;
       Fp continuation;
 
     public:
- explicit future_deferred_continuation_shared_state(
+ future_deferred_continuation_shared_state(
           F& f, BOOST_THREAD_FWD_REF(Fp) c
           ) :
- parent(f),
+ parent(f.future_),
           //continuation(boost::forward<Fp>(c)
           continuation(c)
       {
@@ -3583,14 +3583,14 @@
     template<typename F, typename Fp>
     struct future_deferred_continuation_shared_state<F,void,Fp>: shared_state<void>
     {
- F& parent;
+ F parent;
       Fp continuation;
 
     public:
- explicit future_deferred_continuation_shared_state(
+ future_deferred_continuation_shared_state(
           F& f, BOOST_THREAD_FWD_REF(Fp) c
           ):
- parent(f),
+ parent(f.future_),
           continuation(boost::move(c))
       {
         this->set_deferred();
@@ -3661,12 +3661,6 @@
     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
-// if (this->future_==0)
-// {
-// // fixme what to do when the future has no associated state?
-// return BOOST_THREAD_FUTURE<future_type>();
-// }
-
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(policy) & int(launch::async))
     {
@@ -3682,9 +3676,7 @@
     }
     else
     {
- // fixme what to do when the policy is invalid?
       BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
- //return BOOST_THREAD_FUTURE<future_type>();
     }
 
   }
@@ -3697,13 +3689,6 @@
     typedef typename boost::result_of<F(BOOST_THREAD_FUTURE<R>&)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
-// if (this->future_==0)
-// {
-// //BOOST_THREAD_LOG << "ERROR future::then " << this << BOOST_THREAD_END_LOG;
-// // fixme what to do when the future has no associated state?
-// return BOOST_THREAD_FUTURE<future_type>();
-// }
-
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(this->launch_policy()) & int(launch::async))
     {
@@ -3720,9 +3705,7 @@
     }
     else
     {
- // fixme what to do when the policy is invalid?
       BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
- //return BOOST_THREAD_FUTURE<future_type>();
     }
   }
 
@@ -3789,12 +3772,6 @@
     typedef typename boost::result_of<F(shared_future<R>&)>::type future_type;
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
 
-// if (this->future_==0)
-// {
-// // fixme what to do when the future has no associated state?
-// return BOOST_THREAD_FUTURE<future_type>();
-// }
-
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(policy) & int(launch::async))
     {
@@ -3810,9 +3787,7 @@
     }
     else
     {
- // fixme what to do when the policy is invalid?
       BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
- //return BOOST_THREAD_FUTURE<future_type>();
     }
 
   }
@@ -3825,12 +3800,6 @@
     typedef typename boost::result_of<F(shared_future<R>&)>::type future_type;
 
     BOOST_THREAD_ASSERT_PRECONDITION(this->future_!=0, future_uninitialized());
-// if (this->future_==0)
-// {
-// //BOOST_THREAD_LOG << "ERROR future::then " << this << BOOST_THREAD_END_LOG;
-// // fixme what to do when the future has no associated state?
-// return BOOST_THREAD_FUTURE<future_type>();
-// }
 
     boost::unique_lock<boost::mutex> lock(this->future_->mutex);
     if (int(this->launch_policy()) & int(launch::async))
@@ -3848,21 +3817,66 @@
     }
     else
     {
- // fixme what to do when the policy is invalid?
       BOOST_THREAD_ASSERT_PRECONDITION(false && "invalid launch parameter", std::logic_error("invalid launch parameter"));
- //return BOOST_THREAD_FUTURE<future_type>();
     }
   }
 #endif
 #if defined BOOST_THREAD_PROVIDES_FUTURE_UNWRAP
   namespace detail
   {
+
+ /////////////////////////
+ /// future_unwrap_shared_state
+ /////////////////////////
+
+ template<typename Rp>
+ struct future_unwrap_shared_state: future_async_shared_state_base<Rp>
+ {
+ typedef boost::shared_ptr<detail::shared_state<R> > future_ptr;
+
+ future_ptr parent_;
+ public:
+ explicit future_async_continuation_shared_state(
+ F& f, BOOST_THREAD_FWD_REF(Fp) c
+ ) :
+ parent(f.future_),
+ continuation(c)
+ {
+ }
+
+ void launch_continuation(boost::unique_lock<boost::mutex>& lock)
+ {
+ lock.unlock();
+ this->thr_ = thread(&future_async_continuation_shared_state::run, this);
+ }
+
+ static void run(future_async_continuation_shared_state* that)
+ {
+ try
+ {
+ that->mark_finished_with_result(that->continuation(that->parent));
+ }
+#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
+ catch(thread_interrupted& )
+ {
+ that->mark_interrupted_finish();
+ }
+#endif
+ catch(...)
+ {
+ that->mark_exceptional_finish();
+ }
+ }
+ };
+
     template <class Rp>
     typename BOOST_THREAD_FUTURE<Rp>::value_type
     make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock, BOOST_THREAD_FUTURE<Rp>& f)
     {
- shared_ptr<future_unwrap_shared_state<Rp> >
- h(new future_unwrap_shared_state<Rp>(f, boost::forward<Fp>(c)));
+
+ typedef typename BOOST_THREAD_FUTURE<Rp>::value_type future_value_type;
+ shared_ptr<future_unwrap_shared_state<future_value_type> >
+ h(new future_unwrap_shared_state<future_value_type>(f.future_));
       f.future_->set_continuation_ptr(h, lock);
       return BOOST_THREAD_FUTURE<Rp>(h);
     }

Modified: trunk/libs/thread/test/sync/futures/future/then_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/future/then_pass.cpp Sat Jun 8 04:21:34 2013 (r84684)
+++ trunk/libs/thread/test/sync/futures/future/then_pass.cpp 2013-06-08 06:53:46 EDT (Sat, 08 Jun 2013) (r84685)
@@ -20,6 +20,7 @@
 
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
 
+
 int p1()
 {
   BOOST_THREAD_LOG << "p1 < " << BOOST_THREAD_END_LOG;
@@ -38,10 +39,20 @@
   return 2 * i;
 }
 
+void p3(boost::future<int>& f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " <<i << BOOST_THREAD_END_LOG;
+ return;
+}
+
 int main()
 {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
- BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
     boost::future<int> f1 = boost::async(boost::launch::async, &p1);
     BOOST_TEST(f1.valid());
     boost::future<int> f2 = f1.then(&p2);
@@ -63,6 +74,27 @@
   }
   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
+ boost::future<int> f1 = boost::async(boost::launch::async, &p1);
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(&p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
     boost::future<int> f2 = boost::async(p1).then(&p2);
     BOOST_TEST(f2.get()==2);
   }

Modified: trunk/libs/thread/test/sync/futures/promise/default_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/promise/default_pass.cpp Sat Jun 8 04:21:34 2013 (r84684)
+++ trunk/libs/thread/test/sync/futures/promise/default_pass.cpp 2013-06-08 06:53:46 EDT (Sat, 08 Jun 2013) (r84685)
@@ -38,9 +38,7 @@
   }
   {
       boost::promise<void> p;
- std::cout << __LINE__ << std::endl;
       boost::future<void> f = BOOST_THREAD_MAKE_RV_REF(p.get_future());
- std::cout << __LINE__ << std::endl;
       BOOST_TEST(f.valid());
   }
 

Modified: trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp
==============================================================================
--- trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp Sat Jun 8 04:21:34 2013 (r84684)
+++ trunk/libs/thread/test/sync/futures/shared_future/then_pass.cpp 2013-06-08 06:53:46 EDT (Sat, 08 Jun 2013) (r84685)
@@ -38,10 +38,20 @@
   return 2 * i;
 }
 
+void p3(boost::shared_future<int>& f)
+{
+ BOOST_THREAD_LOG << "p3 <" << &f << BOOST_THREAD_END_LOG;
+ BOOST_TEST(f.valid());
+ int i = f.get();
+ boost::this_thread::sleep_for(boost::chrono::milliseconds(500));
+ BOOST_THREAD_LOG << "p3 <" << &f << " " << i << BOOST_THREAD_END_LOG;
+ return ;
+}
+
 int main()
 {
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
- BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
     boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
     BOOST_TEST(f1.valid());
     boost::future<int> f2 = f1.then(&p2);
@@ -63,6 +73,27 @@
   }
   BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
   {
+ boost::shared_future<int> f1 = boost::async(boost::launch::async, &p1).share();
+ BOOST_TEST(f1.valid());
+ boost::future<void> f2 = f1.then(&p3);
+ BOOST_TEST(f2.valid());
+ try
+ {
+ f2.wait();
+ }
+ catch (std::exception& ex)
+ {
+ BOOST_THREAD_LOG << "ERRORRRRR "<<ex.what() << "" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ catch (...)
+ {
+ BOOST_THREAD_LOG << " ERRORRRRR exception thrown" << BOOST_THREAD_END_LOG;
+ BOOST_TEST(false);
+ }
+ }
+ BOOST_THREAD_LOG << BOOST_THREAD_END_LOG;
+ {
     boost::future<int> f2 = boost::async(p1).share().then(&p2);
     BOOST_TEST(f2.get()==2);
   }


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