A followup with reference to the upcoming feature in C++20 from n3721 "Improvements to std::future and related APIs"
#include <iostream>
#include <future>
#include <exception>
using std::cout;
using std::endl;
int main() {
auto prom_one = std::promise<std::future<int>>{};
auto fut_one = prom_one.get_future();
std::thread{[prom_one = std::move(prom_one)]() mutable {
auto prom_two = std::promise<int>{};
auto fut_two = prom_two.get_future();
prom_two.set_value(1);
prom_one.set_value(std::move(fut_two));
}}.detach();
auto inner_fut_unwrap = fut_one.unwrap();
auto inner_fut_get = fut_one.get();
auto th_one = std::thread{[&]() {
cout << inner_fut_unwrap.get() << endl;
}};
auto th_two = std::thread{[&]() {
cout << inner_fut_get.get() < endl;
}};
th_one.join();
th_two.join();
return 0;
}
In the code above, which will win the race to print 1
? th_one
or th_two
?
To clarify what race I was talking about, there are two (potential) racy situations here, the latter being the one that is really confusing me.
The first is in the setting and unwrapping of the inner future; the unwrapped future should act as a suitable proxy for the inner future even when the actual set_value
has not been called on the inner future. So unwrap()
must return a proxy that exposes a thread safe interface regardless of what happens on the other side.
The other situation is what happens to a get()
from a future when a proxy for it already exists elsewhere, in this example inner_fut_unwrap
is the proxy for inner_fut_get
. In such a situation, which should win the race? The unwrapped future or the future fetched via a call to get()
on the outer future?