std::future still deferred when using std::packaged_task (VS11)
Asked Answered
P

1

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

Presentationism answered 8/10, 2012 at 3:10 Comment(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.Omega
P
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.

Pyridoxine answered 8/10, 2012 at 6:50 Comment(4)
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)?Presentationism
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.Pyridoxine
@AnthonyWilliams Thanks for boost support. It is something that can be relied on for thisOmega
Microsoft has made me quite sad with their broken promises. :'(Daberath

© 2022 - 2024 — McMap. All rights reserved.