boostorg / thread

Boost.org thread module
http://boost.org/libs/thread
201 stars 161 forks source link

`.get()` hangs on unwrapped, deferred future. #358

Open Spongman opened 3 years ago

Spongman commented 3 years ago

Can someone tell my why the .get() call here does not return?

#define BOOST_THREAD_VERSION 5
#include <boost/thread/future.hpp>

int main()
{
    auto outer = boost::make_ready_future();
    outer.set_deferred();
    outer.then([](auto inner) {
        inner.get();
        return boost::make_ready_future();
    })
    .unwrap()
    .get();
}

(this is a minimal repro of this issue in a much larger codebase. i know you could return void from the lambda here and avoid calling unwrap()...)

gcc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0 boost v1.71, v1.77

Spongman commented 3 years ago
#0  futex_wait_cancelable (private=<optimized out>, expected=0, futex_word=0x80543c8) at ../sysdeps/nptl/futex-internal.h:183
#1  __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x8054378, cond=0x80543a0) at pthread_cond_wait.c:508
#2  __pthread_cond_wait (cond=0x80543a0, mutex=0x8054378) at pthread_cond_wait.c:638
#3  0x000000000802238e in boost::posix::pthread_cond_wait (m=0x8054378, c=0x80543a0) at /usr/include/boost/thread/pthread/pthread_helpers.hpp:112
#4  boost::condition_variable::wait (m=..., this=0x8054378) at /usr/include/boost/thread/pthread/condition_variable.hpp:79
#5  boost::condition_variable::wait<boost::_bi::bind_t<bool, boost::_mfi::mf0<bool, boost::detail::shared_state_base>, boost::_bi::list1<boost::reference_wrapper<boost::detail::shared_state_base> > > > (pred=..., m=..., this=0x8054378) at /usr/include/boost/thread/pthread/condition_variable_fwd.hpp:93
#6  boost::detail::shared_state_base::wait_internal (this=0x8054320, lk=..., rethrow=<optimized out>) at /usr/include/boost/thread/future.hpp:396
#7  0x00000000080229b6 in boost::detail::shared_state<void>::get (this=<optimized out>, lock=...) at /usr/include/boost/thread/future.hpp:868
#8  0x0000000008020506 in boost::future<void>::get (this=0x7ffffffed960) at /usr/include/boost/smart_ptr/shared_ptr.hpp:784
#9  0x0000000008010466 in main () at /usr/include/boost/thread/lock_types.hpp:471
void wait_internal(boost::unique_lock<boost::mutex> &lk, bool rethrow=true)
{
  do_callback(lk);
  if (is_deferred_)
  {
    is_deferred_=false;
    execute(lk);
  }
  waiters.wait(lk, boost::bind(&shared_state_base::is_done, boost::ref(*this)));    //// <<<<<----- deadlock
  if(rethrow && exception)
  {
      boost::rethrow_exception(exception);
  }
}
Spongman commented 2 years ago

is this thing on?