http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49204
Summary: remaining issues in <future> Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: r...@gcc.gnu.org ReportedBy: r...@gcc.gnu.org (this is a placeholder and reminder to myself) We don't return future_status from the timed waiting functions. The requirements for async say: If the implementation chooses the launch::async policy, — a call to a waiting function on an asynchronous return object that shares the shared state created by this async call shall block until the associated thread has completed, as if joined (30.3.1.5); The current implementation doesn't meet this requirement, _Async_state::_M_do_run could make the state ready and unblock waiters before the thread completes. Proposed fix: _State_base::_M_wait() already calls _M_run_deferred() to give a deferred function a chance to run, we could add override it as _Async_state::_M_run_deferred() and join the thread. @@ -1325,7 +1325,7 @@ _M_thread(mem_fn(&_Async_state::_M_do_run), this) { } - ~_Async_state() { _M_thread.join(); } + ~_Async_state() { _M_join(); } private: void _M_do_run() @@ -1334,11 +1334,18 @@ _M_set_result(std::move(__setter)); } + void _M_run_deferred() + { _M_join(); } + + void _M_join() + { std::call_once(_M_once, &thread::join, ref(_M_thread)); } + template<typename, typename> friend class _Task_setter; typedef typename __future_base::_Ptr<_Result<_Res>>::type _Ptr_type; _Ptr_type _M_result; std::function<_Res()> _M_fn; thread _M_thread; + once_flag _M_once; }; /// async That would ensure non-timed waiting functions block as if joined. It doesn't handle non-timed waiting functions, but I'm not convinced they should block.