Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::packaged_task not breaking promises on destruction?

I'm encountering something very weird when using packaged tasks. When reading ~packaged_task I get the impression that if a std::packaged_task is destroyed before it is executed, the promise will be broken and an attempt to get the result from the future should throw std::future_error.

However, on Visual Studio 2013 this doesn't seem to be the case. Take this following code:

#include <iostream>
#include <future>
#include <functional>

int main() {
    std::future<int> f;
    {
        std::packaged_task<int()> task([](){return 3; });
        f = task.get_future();
    }
    std::cout<<f.get()<<std::endl;
    return 0;
}

I'm expecting to get an std::future_error on f.get() but instead it blocks, waiting for the packaged task to be executed.

Trying another compiler: http://ideone.com/Wt0WOc does indeed throw a std::future_error("Broken promise")...

Am I seeing a bug in Visual Studio 2013 or have I missed something?

like image 779
Emily L. Avatar asked Sep 10 '14 10:09

Emily L.


2 Answers

You are correct. ~packaged_task() abandons the shared state (§30.6.9.1 [futures.task.members]/p9), which means, if the shared state is not ready, storing an exception object of type future_error with error condition of broken_promise, then making the shared state ready; and then releasing the shared state (§30.6.4 [futures.state]/p7).

This is a known bug that will be fixed in the next version of Visual Studio, which is likely to come out some time in 2015. It's also fixed in the CTP, but it's a pretty bad idea to use that for production code...

like image 150
T.C. Avatar answered Nov 04 '22 18:11

T.C.


I think it's a bug, the standard says ~packaged_task abandons the shared state, which means that if it isn't ready yet it should store a broken_promise exception and make the state ready, just as you expect.

Full disclosure: your ideone.com test uses GCC and I implemented GCC's <future> so I might be biased when I say its behaviour is correct ... but I think it is still correct ;-)

like image 7
Jonathan Wakely Avatar answered Nov 04 '22 17:11

Jonathan Wakely