OSDN Git Service

PR libstdc++/50862
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / condition_variable
index d59fdd4..e17f326 100644 (file)
@@ -22,7 +22,7 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file condition_variable
+/** @file include/condition_variable
  *  This is a Standard C++ Library header.
  */
 
@@ -32,7 +32,7 @@
 #pragma GCC system_header
 
 #ifndef __GXX_EXPERIMENTAL_CXX0X__
-# include <c++0x_warning.h>
+# include <bits/c++0x_warning.h>
 #else
 
 #include <chrono>
 
 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
 
-namespace std
+namespace std _GLIBCXX_VISIBILITY(default)
 {
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
   /**
    * @defgroup condition_variables Condition Variables
    * @ingroup concurrency
@@ -58,22 +60,27 @@ namespace std
   {
     typedef chrono::system_clock       __clock_t;
     typedef __gthread_cond_t           __native_type;
+
+#ifdef __GTHREAD_COND_INIT
+    __native_type                      _M_cond = __GTHREAD_COND_INIT;
+#else
     __native_type                      _M_cond;
+#endif
 
   public:
     typedef __native_type*             native_handle_type;
 
-    condition_variable() throw ();
-    ~condition_variable() throw ();
+    condition_variable() noexcept;
+    ~condition_variable() noexcept;
 
     condition_variable(const condition_variable&) = delete;
     condition_variable& operator=(const condition_variable&) = delete;
 
     void
-    notify_one();
+    notify_one() noexcept;
 
     void
-    notify_all();
+    notify_all() noexcept;
 
     void
     wait(unique_lock<mutex>& __lock);
@@ -162,30 +169,55 @@ namespace std
   };
 
   /// condition_variable_any
-  // Like above, only mutex may not have try_lock.
+  // Like above, but mutex is not required to have try_lock.
   class condition_variable_any
   {
-    typedef __gthread_cond_t           __native_type;
-    __native_type                      _M_cond;
+    typedef chrono::system_clock       __clock_t;
+    condition_variable                 _M_cond;
+    mutex                              _M_mutex;
 
   public:
-    typedef __native_type*             native_handle_type;
+    typedef condition_variable::native_handle_type     native_handle_type;
 
-    condition_variable_any() throw ();
-    ~condition_variable_any() throw ();
+    condition_variable_any() noexcept;
+    ~condition_variable_any() noexcept;
 
     condition_variable_any(const condition_variable_any&) = delete;
     condition_variable_any& operator=(const condition_variable_any&) = delete;
 
     void
-    notify_one();
+    notify_one() noexcept
+    {
+      lock_guard<mutex> __lock(_M_mutex);
+      _M_cond.notify_one();
+    }
 
     void
-    notify_all();
+    notify_all() noexcept
+    {
+      lock_guard<mutex> __lock(_M_mutex);
+      _M_cond.notify_all();
+    }
 
     template<typename _Lock>
       void
-      wait(_Lock& __lock);
+      wait(_Lock& __lock)
+      {
+       // scoped unlock - unlocks in ctor, re-locks in dtor
+       struct _Unlock {
+         explicit _Unlock(_Lock& __lk) : _M_lock(__lk) { __lk.unlock(); }
+         ~_Unlock() { _M_lock.lock(); }
+         _Lock& _M_lock;
+       };
+
+       unique_lock<mutex> __my_lock(_M_mutex);
+       _Unlock __unlock(__lock);
+       // _M_mutex must be unlocked before re-locking __lock so move
+       // ownership of _M_mutex lock to an object with shorter lifetime.
+       unique_lock<mutex> __my_lock2(std::move(__my_lock));
+       _M_cond.wait(__my_lock2);
+      }
+      
 
     template<typename _Lock, typename _Predicate>
       void
@@ -198,7 +230,14 @@ namespace std
     template<typename _Lock, typename _Clock, typename _Duration>
       cv_status
       wait_until(_Lock& __lock,
-                const chrono::time_point<_Clock, _Duration>& __atime);
+                const chrono::time_point<_Clock, _Duration>& __atime)
+      {
+        unique_lock<mutex> __my_lock(_M_mutex);
+        __lock.unlock();
+        cv_status __status = _M_cond.wait_until(__my_lock, __atime);
+        __lock.lock();
+        return __status;
+      }
 
     template<typename _Lock, typename _Clock,
             typename _Duration, typename _Predicate>
@@ -215,21 +254,20 @@ namespace std
 
     template<typename _Lock, typename _Rep, typename _Period>
       cv_status
-      wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime);
+      wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime)
+      { return wait_until(__lock, __clock_t::now() + __rtime); }
 
     template<typename _Lock, typename _Rep,
             typename _Period, typename _Predicate>
       bool
       wait_for(_Lock& __lock,
-              const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p);
-
-    native_handle_type
-    native_handle()
-    { return &_M_cond; }
+              const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p)
+      { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
   };
 
   // @} group condition_variables
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace
 
 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1