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.

Reply via email to