Opened 8 years ago

Closed 7 years ago

#11220 closed Bugs (invalid)

future<>::wait_for() on continuation doesn't return after timeout.

Reported by: Konrad Zemek <konrad.zemek@…> Owned by: viboes
Milestone: To Be Determined Component: thread
Version: Boost 1.58.0 Severity: Problem
Keywords: wait_for future continuation Cc:

Description

If the original future's value will never be set, the wait_for() on continuation will deadlock.

I'm using Boost 1.58 with Thread patched to commit 0bed674233a3c94b7254037dc4903961b54eb141 .

Example to reproduce:

#define BOOST_THREAD_VERSION 4
#define BOOST_THREAD_PROVIDES_EXECUTORS

#include <boost/thread.hpp>
#include <boost/thread/executor.hpp>
#include <boost/thread/thread_pool.hpp>

#include <future>
#include <chrono>

void wait_for() {
      boost::promise<void> promise;
      auto future = promise.get_future();
      future.wait_for(boost::chrono::milliseconds(100));
}

void wait_for_executor() {
      boost::promise<void> promise;
      auto future = promise.get_future();
      auto far_future = future.then(boost::launch::async, [](auto){});
      far_future.wait_for(boost::chrono::milliseconds(100));
}

int main() {
      // works
      wait_for();

      // deadlocks
      wait_for_executor();
}

GDB backtrace:

Thread 1 (Thread 0x7ffff7fe6780 (LWP 247)):
#0  pthread_cond_wait@@GLIBC_2.3.2 ()
    at ../nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:185
#1  0x000000000040df1e in boost::condition_variable::wait (this=0x63f3e8, m=...)
    at /usr/include/boost/thread/pthread/condition_variable.hpp:73
#2  0x00000000004105a1 in boost::detail::shared_state_base::wait_internal (this=0x63f380, 
    lk=..., rethrow=false) at /usr/include/boost/thread/future.hpp:305
#3  0x000000000041061a in boost::detail::shared_state_base::wait (this=0x63f380, lock=..., 
    rethrow=false) at /usr/include/boost/thread/future.hpp:315
#4  0x0000000000422c1f in boost::detail::future_async_shared_state_base<void>::wait (
    this=0x63f380, lk=..., rethrow=false) at /usr/include/boost/thread/future.hpp:771
#5  0x0000000000422bb6 in boost::detail::future_async_shared_state_base<void>::block_if_needed
    (this=0x63f380, lk=...) at /usr/include/boost/thread/future.hpp:757
#6  0x000000000040fed6 in boost::detail::shared_state_base::dec (this=0x63f380, lk=...)
    at /usr/include/boost/thread/future.hpp:181
#7  0x000000000040ff1e in boost::detail::shared_state_base::dec (this=0x63f380)
    at /usr/include/boost/thread/future.hpp:184
#8  0x000000000041a2b6 in boost::detail::basic_future<void>::~basic_future (
    this=0x7fffffffeb80, __in_chrg=<optimized out>)
    at /usr/include/boost/thread/future.hpp:1188
#9  0x00000000004147ca in boost::future<void>::~future (this=0x7fffffffeb80, 
    __in_chrg=<optimized out>) at /usr/include/boost/thread/future.hpp:1541
#10 0x000000000040a920 in wait_for_executor () at wait_for_example.cpp:20
#11 0x000000000040a99f in main () at wait_for_example.cpp:29

Change History (3)

comment:1 by Konrad Zemek <konrad.zemek@…>, 8 years ago

I've just noticed - it's not wait_for that locks, it's the far_future's destructor that locks here, which is consistent with the documentation:

The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block.

I will have to find a workaround, but it's not a bug.

comment:2 by viboes, 7 years ago

Owner: changed from Anthony Williams to viboes
Status: newassigned

comment:3 by viboes, 7 years ago

Resolution: invalid
Status: assignedclosed
Note: See TracTickets for help on using tickets.