Re: [Boost-bugs] [Boost C++ Libraries] #11256: future<>::is_ready() == false in continuation function

Subject: Re: [Boost-bugs] [Boost C++ Libraries] #11256: future<>::is_ready() == false in continuation function
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2015-05-03 18:49:42


#11256: future<>::is_ready() == false in continuation function
-------------------------------------+-------------------------------------
  Reporter: Konrad Zemek | Owner: viboes
  <konrad.zemek@…> | Status: assigned
      Type: Bugs | Component: thread
 Milestone: To Be Determined | Severity: Problem
   Version: Boost 1.58.0 | Keywords: then continuation
Resolution: | is_ready
-------------------------------------+-------------------------------------

Comment (by viboes):

 The following design seems to work well except for the example
 future_unwrap.cpp.

 The unwrap shared state adds a continuation on the wrapped shared state.
 There is no redefinition for wait or get neither the set_continuation_ptr.

 Please could you try it?


 {{{
   template<typename F, typename Rp>
   struct future_unwrap_shared_state: shared_state<Rp>
   {
     F wrapped;
     typename F::value_type unwrapped;
   public:
     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
     : wrapped(boost::move(f)) {
     }

     void launch_continuation(boost::unique_lock<boost::mutex>& lk,
 shared_ptr<shared_state_base> that)
     {
       if (! unwrapped.valid() )
       {
         unwrapped = wrapped.get();
         if (unwrapped.valid())
         {
           boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
         } else {
 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()),
 lk);
         }
       } else {
         this->mark_finished_with_result_internal(unwrapped.get(), lk);
       }
     }
   };

   template<typename F>
   struct future_unwrap_shared_state<F,void>: shared_state<void>
   {
     F wrapped;
     typename F::value_type unwrapped;
   public:
     explicit future_unwrap_shared_state(BOOST_THREAD_RV_REF(F) f)
     : wrapped(boost::move(f)) {
     }

     void launch_continuation(boost::unique_lock<boost::mutex>& lk,
 shared_ptr<shared_state_base> that)
     {
       if (! unwrapped.valid() )
       {
         unwrapped = wrapped.get();
         if (unwrapped.valid())
         {
           lk.unlock();
           boost::unique_lock<boost::mutex> lk2(unwrapped.future_->mutex);
 unwrapped.future_->set_continuation_ptr(this->shared_from_this(), lk2);
         } else {
 this->mark_exceptional_finish_internal(boost::copy_exception(future_uninitialized()),
 lk);
         }
       } else {
         unwrapped.wait();
         this->mark_finished_with_result_internal(lk);
       }
     }
   };


   template <class F, class Rp>
   BOOST_THREAD_FUTURE<Rp>
   make_future_unwrap_shared_state(boost::unique_lock<boost::mutex> &lock,
 BOOST_THREAD_RV_REF(F) f) {
     shared_ptr<future_unwrap_shared_state<F, Rp> >
         h(new future_unwrap_shared_state<F, Rp>(boost::move(f)));
     lock.lock();
     h->wrapped.future_->set_continuation_ptr(h, lock);
     lock.unlock();
     return BOOST_THREAD_FUTURE<Rp>(h);
   }
 }}}

-- 
Ticket URL: <https://svn.boost.org/trac/boost/ticket/11256#comment:11>
Boost C++ Libraries <http://www.boost.org/>
Boost provides free peer-reviewed portable C++ source libraries.

This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:18 UTC