Reputation: 31
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
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
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