]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/std/future
Update copyright years in libstdc++-v3/
[thirdparty/gcc.git] / libstdc++-v3 / include / std / future
index 30100fe05e488dfc211462d3110c4f03492ba497..ca3dacd5588cefd1209646fec3a4e1c82a49aad7 100644 (file)
@@ -1,6 +1,6 @@
 // <future> -*- C++ -*-
 
-// Copyright (C) 2009-2013 Free Software Foundation, Inc.
+// Copyright (C) 2009-2014 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
@@ -46,6 +46,7 @@
 #include <bits/shared_ptr.h>
 #include <bits/uses_allocator.h>
 #include <bits/alloc_traits.h>
+#include <ext/aligned_buffer.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
@@ -206,12 +207,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       struct _Result : _Result_base
       {
       private:
-       typedef alignment_of<_Res>                              __a_of;
-       typedef aligned_storage<sizeof(_Res), __a_of::value>    __align_storage;
-       typedef typename __align_storage::type                  __align_type;
-
-       __align_type            _M_storage;
-       bool                    _M_initialized;
+       __gnu_cxx::__aligned_buffer<_Res>       _M_storage;
+       bool                                    _M_initialized;
 
       public:
        typedef _Res result_type;
@@ -226,26 +223,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
        // Return lvalue, future will add const or rvalue-reference
        _Res&
-       _M_value() noexcept { return *static_cast<_Res*>(_M_addr()); }
+       _M_value() noexcept { return *_M_storage._M_ptr(); }
 
        void
        _M_set(const _Res& __res)
        {
-         ::new (_M_addr()) _Res(__res);
+         ::new (_M_storage._M_addr()) _Res(__res);
          _M_initialized = true;
        }
 
        void
        _M_set(_Res&& __res)
        {
-         ::new (_M_addr()) _Res(std::move(__res));
+         ::new (_M_storage._M_addr()) _Res(std::move(__res));
          _M_initialized = true;
        }
 
       private:
        void _M_destroy() { delete this; }
-
-       void* _M_addr() noexcept { return static_cast<void*>(&_M_storage); }
     };
 
     /// A unique_ptr based on the instantiating type.
@@ -303,7 +298,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     /// Base class for state between a promise and one or more
     /// associated futures.
-    class _State_base
+    class _State_baseV2
     {
       typedef _Ptr<_Result_base> _Ptr_type;
 
@@ -314,15 +309,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       once_flag                        _M_once;
 
     public:
-      _State_base() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT) { }
-      _State_base(const _State_base&) = delete;
-      _State_base& operator=(const _State_base&) = delete;
-      virtual ~_State_base();
+      _State_baseV2() noexcept : _M_result(), _M_retrieved(ATOMIC_FLAG_INIT)
+       { }
+      _State_baseV2(const _State_baseV2&) = delete;
+      _State_baseV2& operator=(const _State_baseV2&) = delete;
+      virtual ~_State_baseV2() = default;
 
       _Result_base&
       wait()
       {
-       _M_run_deferred();
+       _M_complete_async();
        unique_lock<mutex> __lock(_M_mutex);
        _M_cond.wait(__lock, [&] { return _M_ready(); });
        return *_M_result;
@@ -333,8 +329,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         wait_for(const chrono::duration<_Rep, _Period>& __rel)
         {
          unique_lock<mutex> __lock(_M_mutex);
-         if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+         if (_M_ready())
            return future_status::ready;
+         if (_M_has_deferred())
+           return future_status::deferred;
+         if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready(); }))
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 2100.  timed waiting functions must also join
+             _M_complete_async();
+             return future_status::ready;
+           }
          return future_status::timeout;
        }
 
@@ -343,8 +348,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
         {
          unique_lock<mutex> __lock(_M_mutex);
-         if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+         if (_M_ready())
            return future_status::ready;
+         if (_M_has_deferred())
+           return future_status::deferred;
+         if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready(); }))
+           {
+             // _GLIBCXX_RESOLVE_LIB_DEFECTS
+             // 2100.  timed waiting functions must also join
+             _M_complete_async();
+             return future_status::ready;
+           }
          return future_status::timeout;
        }
 
@@ -354,7 +368,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         bool __set = __ignore_failure;
         // all calls to this function are serialized,
         // side-effects of invoking __res only happen once
-        call_once(_M_once, &_State_base::_M_do_set, this, ref(__res),
+        call_once(_M_once, &_State_baseV2::_M_do_set, this, ref(__res),
             ref(__set));
         if (!__set)
           __throw_future_error(int(future_errc::promise_already_satisfied));
@@ -366,7 +380,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        if (static_cast<bool>(__res))
          {
            error_code __ec(make_error_code(future_errc::broken_promise));
-           __res->_M_error = copy_exception(future_error(__ec));
+           __res->_M_error = make_exception_ptr(future_error(__ec));
            {
              lock_guard<mutex> __lock(_M_mutex);
              _M_result.swap(__res);
@@ -398,7 +412,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
           typename promise<_Res>::_Ptr_type operator()()
           {
-            _State_base::_S_check(_M_promise->_M_future);
+            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_set(_M_arg);
             return std::move(_M_promise->_M_storage);
           }
@@ -412,7 +426,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         {
           typename promise<_Res>::_Ptr_type operator()()
           {
-            _State_base::_S_check(_M_promise->_M_future);
+            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_set(std::move(_M_arg));
             return std::move(_M_promise->_M_storage);
           }
@@ -428,7 +442,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         {
           typename promise<_Res>::_Ptr_type operator()()
           {
-            _State_base::_S_check(_M_promise->_M_future);
+            _State_baseV2::_S_check(_M_promise->_M_future);
             _M_promise->_M_storage->_M_error = _M_ex;
             return std::move(_M_promise->_M_storage);
           }
@@ -477,15 +491,24 @@ _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() { }
+      // Wait for completion of async function.
+      virtual void _M_complete_async() { }
+
+      // Return true if state contains a deferred function.
+      virtual bool _M_has_deferred() const { return false; }
     };
 
+#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
+    class _State_base;
+    class _Async_state_common;
+#else
+    using _State_base = _State_baseV2;
+    class _Async_state_commonV2;
+#endif
+
     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_impl;
 
@@ -543,6 +566,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       void _M_destroy() { delete this; }
     };
 
+#ifndef _GLIBCXX_ASYNC_ABI_COMPAT
 
   /// Common implementation for future and shared_future.
   template<typename _Res>
@@ -1444,26 +1468,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Ptr_type _M_result;
       _BoundFn _M_fn;
 
+      // Run the deferred function.
       virtual void
-      _M_run_deferred()
+      _M_complete_async()
       {
         // safe to call multiple times so ignore failure
         _M_set_result(_S_task_setter(_M_result, _M_fn), true);
       }
+
+      virtual bool
+      _M_has_deferred() const { return static_cast<bool>(_M_result); }
     };
 
-  class __future_base::_Async_state_common : public __future_base::_State_base
+  class __future_base::_Async_state_commonV2
+    : public __future_base::_State_base
   {
   protected:
-#ifdef _GLIBCXX_ASYNC_ABI_COMPAT
-    ~_Async_state_common();
-#else
-    ~_Async_state_common() = default;
-#endif
+    ~_Async_state_commonV2() = default;
 
-    // Allow non-timed waiting functions to block until the thread completes,
-    // as if joined.
-    virtual void _M_run_deferred() { _M_join(); }
+    // Make waiting functions block until the thread completes, as if joined.
+    virtual void _M_complete_async() { _M_join(); }
 
     void _M_join() { std::call_once(_M_once, &thread::join, ref(_M_thread)); }
 
@@ -1473,7 +1497,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _BoundFn, typename _Res>
     class __future_base::_Async_state_impl final
-    : public __future_base::_Async_state_common
+    : public __future_base::_Async_state_commonV2
     {
     public:
       explicit
@@ -1541,6 +1565,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                   std::forward<_Args>(__args)...);
     }
 
+#endif // _GLIBCXX_ASYNC_ABI_COMPAT
 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
        // && ATOMIC_INT_LOCK_FREE