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 14:48:56


#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):

 I'm not yet sure but I believe that I find where the bug is. A unwrapped
 future shouldn't
 is not a continuation so no need for the adding it self as a continuation
 at the construction time


 {{{
   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->parent.future_->set_continuation_ptr(h, lock);
 // lock.unlock();

     return BOOST_THREAD_FUTURE<Rp>(h);
   }

 }}}

 In addition the name of the wrapped future was misleading (parent). The
 code


 {{{
     virtual void set_continuation_ptr(continuation_ptr_type continuation,
 boost::unique_lock<boost::mutex>& lock)
     {
       boost::unique_lock<boost::mutex> lk(wrapped.parent.future_->mutex);
       parent.future_->set_continuation_ptr(continuation, lk);
     }

 }}}


 was setting a continuation on the wrapped (and already ready future, not
 on the parent one).

 The code should be

 {{{
     virtual void set_continuation_ptr(continuation_ptr_type continuation,
 boost::unique_lock<boost::mutex>& lock)
     {
       boost::unique_lock<boost::mutex> lk(wrapped.parent.future_->mutex);
       parent.parent.future_->set_continuation_ptr(continuation, lk);
     }

 }}}

 I've renamed the parent member to wrapped.

 Please, could you try with this change


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

     typename F::value_type parent_value(boost::unique_lock<boost::mutex>&
 ) {
         typename F::value_type r = wrapped.get();
         r.set_exceptional_if_invalid();
         return boost::move(r);
     }

     virtual void wait(boost::unique_lock<boost::mutex>& lk, bool ) { //
 todo see if rethrow must be used
         parent_value(lk).wait();
     }
     virtual Rp get(boost::unique_lock<boost::mutex>& lk) {
         return parent_value(lk).get();
     }
 #if defined BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
     typedef shared_ptr<shared_state_base> continuation_ptr_type;

     virtual void set_continuation_ptr(continuation_ptr_type continuation,
 boost::unique_lock<boost::mutex>& lock)
     {
       boost::unique_lock<boost::mutex> lk(wrapped.parent.future_->mutex);
       wrapped.parent.future_->set_continuation_ptr(continuation, lk);
     }
 #endif
   };

   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->parent.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:8>
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