Monday, May 6, 2013

Shared State from std::async remains special

In an earlier post, I pointed out that, contrary to the way things are generally described, it's not the futures returned from std::async that are special, it's the shared state they refer to that is. In the comments that followed that post, it was pointed out that this could change in C++14, but the proposal to that effect was rejected at the standardization committee meeting last month. As Anthony Williams put it in his blog post,
Herb Sutter's late paper on the behaviour of the destructor of std::future (N3630) was up next. This is a highly conterversial topic, and yielded much discussion. The crux of the matter is that as currently specified the destructor of std::future blocks if it came from an invocation of std::async, the asynchronous function was run on a separate thread (with the std::launch::async policy), and that thread has not yet finished.
 Much of the discussion focused on the potential for breaking existing code, and ways of preventing this. The proposal eventually morphed into a new paper (N3637) which created 2 new types of future: waiting_future and shared_waiting_future. std::async would then be changed to return a waiting_future instead of a future. Existing code that compiled unchanged would then keep the existing behaviour; code that changed behaviour would fail to compile. Though the change required to get the desired behaviour would not be extensive, the feeling in the full committee was that this breakage would be too extensive, and the paper was also voted down in full committee.
C++14 now has CD ("committee draft") status, but that doesn't mean things can't change. A member of the committee emailed me as follows:
[The] paper on changing [the behavior of futures referring to shared state from std::async] was rejected, after a LOT of discussion. The discussion has continued on the reflector, and we may get a NB comment on the C++14 draft about it, but for now there is no change.
My impression is that many committee-watchers had considered a change in the specification for std::async to be a sure thing, but, as I wrote in yet another blog post, the committee tends to be quite conservative about the possibility of breaking existing code. At this point, that looks to be the line they're going to follow as regards the behavior of (the shared state corresponding to) futures produced by std::async.



Tianyu Zhu said...

Wow, that really a shame. It would have been nice if they figured this out before C++11 instead of trying to maintain backwards compatibility now.

Michael Marcin said...

Very disappointing, there's not even a fully conforming released c++11 compiler yet. Seems like there should still be time to correct this.

Scott Meyers said...

@Michael Marcin: I just got word from a member of the committee that there are plans to put forward a revised proposal at the next standardization meeting, and "we're optimistic about its chances." I have no details about this revised proposal, and of course there's no way to say what will happen when it's considered, but I think it's fair to say that this matter is not yet fully settled.

topoden said...

I wonder why wouldn't they consider adding one more bitmask value parameter to 'async'. The parameter that is similar to launch policy, say 'release policy'. The parameter would have say 'terminate', 'detach' and 'join' values. It would also have a default value that would bitwise include all the values and would mean the behaviour the shared state uses right now. That way all current code would be kept correct (as it would use the default value) and the new code writers would have a chance to specify 'release policy' as they need.