// 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.
*/
#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
{
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);
};
/// 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
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>
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