OSDN Git Service

* include/std/future (atomic_future): Remove declaration of
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / future
index 4591eb6..98c7b84 100644 (file)
@@ -1,6 +1,6 @@
 // <future> -*- C++ -*-
 
-// Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -60,10 +60,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// Error code for futures
   enum class future_errc
   {
-    broken_promise,
-    future_already_retrieved,
+    future_already_retrieved = 1,
     promise_already_satisfied,
-    no_state
+    no_state,
+    broken_promise
   };
 
   /// Specialization.
@@ -113,9 +113,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _Res>
     class shared_future;
 
-  template<typename _Res>
-    class atomic_future;
-
   template<typename _Signature>
     class packaged_task;
 
@@ -187,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     async(_Fn&& __fn, _Args&&... __args);
 
 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
-  && defined(_GLIBCXX_ATOMIC_BUILTINS_4)
+  && (ATOMIC_INT_LOCK_FREE > 1)
 
   /// Base class and enclosing scope.
   struct __future_base
@@ -264,10 +261,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Result_alloc.
     template<typename _Res, typename _Alloc>
-      struct _Result_alloc : _Result<_Res>, _Alloc
+      struct _Result_alloc final : _Result<_Res>, _Alloc
       {
-        typedef typename _Alloc::template rebind<_Result_alloc>::other
-          __allocator_type;
+        typedef typename allocator_traits<_Alloc>::template
+          rebind_alloc<_Result_alloc> __allocator_type;
 
         explicit
        _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
@@ -276,9 +273,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       private:
        void _M_destroy()
         {
+         typedef allocator_traits<__allocator_type> __traits;
           __allocator_type __a(*this);
-          __a.destroy(this);
-          __a.deallocate(this, 1);
+         __traits::destroy(__a, this);
+         __traits::deallocate(__a, this, 1);
         }
       };
 
@@ -287,15 +285,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _S_allocate_result(const _Allocator& __a)
       {
         typedef _Result_alloc<_Res, _Allocator>        __result_type;
-        typename __result_type::__allocator_type __a2(__a);
-        __result_type* __p = __a2.allocate(1);
+       typedef allocator_traits<typename __result_type::__allocator_type>
+         __traits;
+        typename __traits::allocator_type __a2(__a);
+        __result_type* __p = __traits::allocate(__a2, 1);
         __try
        {
-          __a2.construct(__p, __a);
+         __traits::construct(__a2, __p, __a);
         }
         __catch(...)
         {
-          __a2.deallocate(__p, 1);
+         __traits::deallocate(__a2, __p, 1);
           __throw_exception_again;
         }
         return _Ptr<__result_type>(__p);
@@ -325,27 +325,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
        _M_run_deferred();
        unique_lock<mutex> __lock(_M_mutex);
-       if (!_M_ready())
-         _M_cond.wait(__lock, std::bind<bool>(&_State_base::_M_ready, this));
+       _M_cond.wait(__lock, [&] { return _M_ready(); });
        return *_M_result;
       }
 
       template<typename _Rep, typename _Period>
-        bool
+        future_status
         wait_for(const chrono::duration<_Rep, _Period>& __rel)
         {
          unique_lock<mutex> __lock(_M_mutex);
-         auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
-         return _M_ready() || _M_cond.wait_for(__lock, __rel, __bound);
+         if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+           return future_status::ready;
+         return future_status::timeout;
        }
 
       template<typename _Clock, typename _Duration>
-        bool
+        future_status
         wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
         {
          unique_lock<mutex> __lock(_M_mutex);
-         auto __bound = std::bind<bool>(&_State_base::_M_ready, this);
-         return _M_ready() || _M_cond.wait_until(__lock, __abs, __bound);
+         if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+           return future_status::ready;
+         return future_status::timeout;
        }
 
       void
@@ -477,14 +478,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       bool _M_ready() const noexcept { return static_cast<bool>(_M_result); }
 
+      // Misnamed: waits for completion of async function.
       virtual void _M_run_deferred() { }
     };
 
     template<typename _BoundFn, typename = typename _BoundFn::result_type>
       class _Deferred_state;
 
+    class _Async_state_common;
+
     template<typename _BoundFn, typename = typename _BoundFn::result_type>
-      class _Async_state;
+      class _Async_state_impl;
 
     template<typename _Signature>
       class _Task_state;
@@ -570,7 +574,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       template<typename _Rep, typename _Period>
-        bool
+        future_status
         wait_for(const chrono::duration<_Rep, _Period>& __rel) const
         {
           _State_base::_S_check(_M_state);
@@ -578,7 +582,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         }
 
       template<typename _Clock, typename _Duration>
-        bool
+        future_status
         wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
         {
           _State_base::_S_check(_M_state);
@@ -1239,7 +1243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     };
 
   template<typename _Res, typename... _Args>
-    struct __future_base::_Task_state<_Res(_Args...)>
+    struct __future_base::_Task_state<_Res(_Args...)> final
     : __future_base::_State_base
     {
       typedef _Res _Res_type;
@@ -1393,7 +1397,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 
   template<typename _BoundFn, typename _Res>
-    class __future_base::_Deferred_state : public __future_base::_State_base
+    class __future_base::_Deferred_state final
+    : public __future_base::_State_base
     {
     public:
       explicit
@@ -1414,28 +1419,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
     };
 
+  class __future_base::_Async_state_common : public __future_base::_State_base
+  {
+  protected:
+#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
+    ~_Async_state_common();
+#else
+    ~_Async_state_common() = default;
+#endif
+
+    // Allow non-timed waiting functions to block until the thread completes,
+    // as if joined.
+    virtual void _M_run_deferred() { _M_join(); }
+
+    void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
+
+    thread _M_thread;
+    once_flag _M_once;
+  };
+
   template<typename _BoundFn, typename _Res>
-    class __future_base::_Async_state : public __future_base::_State_base
+    class __future_base::_Async_state_impl final
+    : public __future_base::_Async_state_common
     {
     public:
       explicit
-      _Async_state(_BoundFn&& __fn)
-      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn)),
-       _M_thread(mem_fn(&_Async_state::_M_do_run), this)
-      { }
-
-      ~_Async_state() { _M_thread.join(); }
-
-    private:
-      void _M_do_run()
+      _Async_state_impl(_BoundFn&& __fn)
+      : _M_result(new _Result<_Res>()), _M_fn(std::move(__fn))
       {
-        _M_set_result(_S_task_setter(_M_result, _M_fn));
+       _M_thread = std::thread{ [this] {
+         _M_set_result(_S_task_setter(_M_result, _M_fn));
+        } };
       }
 
+      ~_Async_state_impl() { _M_join(); }
+
+    private:
       typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
       _Ptr_type _M_result;
       _BoundFn _M_fn;
-      thread _M_thread;
     };
 
   template<typename _BoundFn>
@@ -1452,7 +1474,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     __future_base::_S_make_async_state(_BoundFn&& __fn)
     {
       typedef typename remove_reference<_BoundFn>::type __fn_type;
-      typedef _Async_state<__fn_type> __state_type;
+      typedef _Async_state_impl<__fn_type> __state_type;
       return std::make_shared<__state_type>(std::move(__fn));
     }
 
@@ -1488,7 +1510,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
-       // && _GLIBCXX_ATOMIC_BUILTINS_4
+       // && ATOMIC_INT_LOCK_FREE
 
   // @} group futures
 _GLIBCXX_END_NAMESPACE_VERSION