It seems that unless you call std::async
a std::future
will never be set to any other state than future_status::deferred
unless you call get
or wait
on the future. wait_for
& wait_until
will continue to not block and return future_status::deferred
even if the task has already run and stored the result.
Here's an example:
#include <future>
void main()
{
auto func = []() { return 5; };
auto asyncFuture = std::async(std::launch::async, func);
auto status = asyncFuture.wait_for(std::chrono::seconds(0)); // timeout (1)
auto deferredFuture = std::async(std::launch::deferred, func);
status = deferredFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
std::packaged_task<int()> task(func);
auto packagedTaskFuture = task.get_future();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
task();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // deferred (2)
packagedTaskFuture.wait();
status = packagedTaskFuture.wait_for(std::chrono::seconds(0)); // ready (0)
}
I don't have the current C++11 standard, but the draft standard in 30.6.9 says that when a packaged_task
is run it should store the result in the future's shared state. It's not very clear whether that includes setting the expected wait_until
/wait_for
behavior or not.
There were previously issues with VS11 behavior in this area with respect to async
calls: http://social.msdn.microsoft.com/Forums/hu/parallelcppnative/thread/4394f2c1-0404-40df-869b-f4fc36fc035c
Additionally it seems like other compilers have problems in this area: C++ 11 future_status::deferred not working
Anyone that may know the standard better: Is this expected behavior or is there an issue with the implemenation in VS11?
Updates: I somehow missed the report for this: http://connect.microsoft.com/VisualStudio/feedback/details/761829/c-11-unexpected-behavior-for-std-future-wait-for-and-std-packaged-task