9

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

Community
  • 1
  • 1
  • Same deferred status is obtained unfortunately by using VS 11 - Update 1, when future is obtained from promise (it works with async). The issue was reported to them a while back ago but is still not functioning. It practically defeats the purpose of using std::future in many cases. Works with boost 1.51 at least. – Ghita Jan 11 '13 at 12:39

1 Answers1

12

This is an issue with VS2012. It's not the only issue either --- their implementation of the C++11 thread library has several bugs. I wrote about a few on my blog.

Anthony Williams
  • 66,628
  • 14
  • 133
  • 155
  • Thanks! I knew the VS11 C++11 STL support was not that great, but I didn't think it'd be completely unusable. Any comments on boost's implementation of these features (obviously not async or things that they haven't implemented yet)? – Kaylyn Bogle Oct 08 '12 at 15:55
  • The boost implementation is generally sound, for the features that are implemented. There are a few bugs, but we're working on them, and Vicente is working on the missing C++11 features. – Anthony Williams Oct 08 '12 at 16:33
  • @AnthonyWilliams Thanks for boost support. It is something that can be relied on for this – Ghita Jan 11 '13 at 12:41
  • 4
    Microsoft has made me quite sad with their broken promises. :'( – Oz. Jul 26 '13 at 04:05