Opened 8 years ago

Closed 7 years ago

#11192 closed Bugs (fixed)

boost::future<>::then() with an executor doesn't compile when the callback returns a future

Reported by: konrad.zemek@… Owned by: viboes
Milestone: Boost 1.60.0 Component: thread
Version: Boost 1.58.0 Severity: Problem
Keywords: future then executor nested Cc:

Description

As noted in the title, when the scheduler overload of boost::future<>::then() is used, and the callback given returns a future, the code doesn't compile.

I'm observing this behavior using Boost 1.58 beta 1.

The minimal code 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>

boost::future<void> p(boost::future<void>) {
    return boost::make_ready_future();
}

int main() {
    // compiles
    boost::make_ready_future().then(&p);

    boost::basic_thread_pool executor;
    // doesn't compile
    boost::make_ready_future().then(executor, &p);
}

I'm getting the following error messages when compiling with GCC 4.9.2:

In file included from /usr/include/boost/thread.hpp:24:0,
                 from example.cpp:4:
/usr/include/boost/thread/future.hpp: In instantiation of 'boost::future<Rp> boost::detail::make_future_executor_continuation_shared_state(Ex&, boost::unique_lock<boost::mutex>&, F&&, Fp&&) [with Ex = boost::executors::basic_thread_pool; F = boost::future<void>; Rp = boost::future<void>; Fp = boost::future<void> (*)(boost::future<void>)]':
/usr/include/boost/thread/future.hpp:4628:12:   required from 'boost::future<typename boost::result_of<F(boost::future<R>)>::type> boost::future<R>::then(Ex&, F&&) [with Ex = boost::executors::basic_thread_pool; F = boost::future<void> (*)(boost::future<void>); R = void; typename boost::result_of<F(boost::future<R>)>::type = boost::future<void>]'
example.cpp:18:49:   required from here
/usr/include/boost/thread/future.hpp:1629:13: error: 'boost::future<boost::future<R> >::future(boost::future<boost::future<R> >::future_ptr) [with R2 = void; boost::future<boost::future<R> >::future_ptr = boost::shared_ptr<boost::detail::shared_state<boost::future<void> > >]' is private
             BOOST_THREAD_FUTURE(future_ptr a_future):
             ^
In file included from /usr/include/boost/thread.hpp:24:0,
                 from example.cpp:4:
/usr/include/boost/thread/future.hpp:4531:37: error: within this context
     return BOOST_THREAD_FUTURE<Rp>(h);

Change History (7)

comment:1 by viboes, 8 years ago

Hrr, I suspect that a friend declaration has been forgotten.

comment:2 by konrad.zemek@…, 8 years ago

I believe this commit fixes the issue in a proper manner: https://github.com/kzemek/thread/commit/60bebc5e8325bf1fcdb3b0ecc586ecccd4200208

It also befriends the nested future specialization with make_shared_future_async_continuation_shared_state and make_shared_future_deferred_continuation_shared_state, as I found that returning a future from shared_future<>::then() also resulted in similar compilation errors.

comment:3 by viboes, 8 years ago

Milestone: To Be DeterminedBoost 1.59.0
Owner: changed from Anthony Williams to viboes
Status: newassigned

Thanks for the patch. I've committed a less ambitious change :( https://github.com/boostorg/thread/commit/45c9a1d7fd16ab828fe9b6aa48e0ac0670e53b02

I will take your changes into account.

comment:4 by viboes, 8 years ago

I have adapted your patch with more missing friend functions

https://github.com/boostorg/thread/commit/0bed674233a3c94b7254037dc4903961b54eb141

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

Thanks, that worked for me. :)

comment:6 by viboes, 7 years ago

Milestone: Boost 1.59.0Boost 1.60.0
Note: See TracTickets for help on using tickets.