vvineett
vvineett

Reputation: 31

boost::future::then() not returning future that blocks on destruction

I wrote this sample code to test boost::future continuations to use in my application.

#include <iostream>
#include <functional>
#include <unistd.h>
#include <exception>

#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION

#include <boost/thread/future.hpp>

void magicNumber(std::shared_ptr<boost::promise<long>> p)
{
    sleep(5);
    p->set_value(0xcafebabe);
}

boost::future<long> foo()
{
    std::shared_ptr<boost::promise<long>> p = 
    std::make_shared<boost::promise<long>>();

    boost::future<long> f = p->get_future();

    boost::thread t([p](){magicNumber(p);});

    t.detach();

    return f;
}

void bar()
{
    auto f = foo();
    f.then([](boost::future<long> f) { std::cout << f.get() << std::endl; });
    std::cout << "Should have blocked?" << std::endl; 
}

int main()
{   
    bar();

    sleep (6);

    return 0;
}

When compiled, linked and run with boost version 1.64.0_1, I am getting following output:

Should have blocked?
3405691582

But according to boost::future::then's documentation here. The execution should be blocked at f.then() in function bar() because the temporary variable of type boost::future<void> should block at destruction, and the output should be

3405691582
Should have blocked?

In my application though, the call to f.then() is blocking the execution till continuation is not invoked. What is happening here?

Upvotes: 3

Views: 813

Answers (1)

sehe
sehe

Reputation: 393084

Note that the only time a future would ever block in the destructor used to be documented as when you use std::async with a launch-policy of launch::async.

See Why is the destructor of a future returned from `std::async` blocking?

The answer lists the many discussions that have taken place around this subject. The proposal N3776 made it into C++14:

This paper provides proposed wording to implement a positive SG1 straw poll to clarify that ~future and ~shared_future don’t block except possibly in the presence of async.

cppreference.com documents std::async

enter image description here

Your code never used async, so it would be surprising if any future derived would block on destruction.

More gener ally, it is clear that the consensus is that blocking destruction is an unfortunate design wart, not something you'd expect being introduced on newer extensions (such as .then continuations).

I can only assume this is a case of documentation error where the wording

  • The returned futures behave as the ones returned from boost::async, the destructor of the future object returned from then will block. This could be subject to change in future versions.

should be removed.

Upvotes: 1

Related Questions