condition_variable [plain text]
#ifndef _LIBCPP_CONDITION_VARIABLE
#define _LIBCPP_CONDITION_VARIABLE
#include <__config>
#include <__mutex_base>
#include <memory>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_VISIBLE condition_variable_any
{
condition_variable __cv_;
shared_ptr<mutex> __mut_;
public:
condition_variable_any();
void notify_one();
void notify_all();
template <class _Lock>
void wait(_Lock& __lock);
template <class _Lock, class _Predicate>
void wait(_Lock& __lock, _Predicate __pred);
template <class _Lock, class _Clock, class _Duration>
cv_status
wait_until(_Lock& __lock,
const chrono::time_point<_Clock, _Duration>& __t);
template <class _Lock, class _Clock, class _Duration, class _Predicate>
bool
wait_until(_Lock& __lock,
const chrono::time_point<_Clock, _Duration>& __t,
_Predicate __pred);
template <class _Lock, class _Rep, class _Period>
cv_status
wait_for(_Lock& __lock,
const chrono::duration<_Rep, _Period>& __d);
template <class _Lock, class _Rep, class _Period, class _Predicate>
bool
wait_for(_Lock& __lock,
const chrono::duration<_Rep, _Period>& __d,
_Predicate __pred);
};
inline _LIBCPP_INLINE_VISIBILITY
condition_variable_any::condition_variable_any()
: __mut_(make_shared<mutex>()) {}
inline _LIBCPP_INLINE_VISIBILITY
void
condition_variable_any::notify_one()
{
{lock_guard<mutex> _(*__mut_);}
__cv_.notify_one();
}
inline _LIBCPP_INLINE_VISIBILITY
void
condition_variable_any::notify_all()
{
{lock_guard<mutex> _(*__mut_);}
__cv_.notify_all();
}
struct __lock_external
{
template <class _Lock>
void operator()(_Lock* __m) {__m->lock();}
};
template <class _Lock>
void
condition_variable_any::wait(_Lock& __lock)
{
shared_ptr<mutex> __mut = __mut_;
unique_lock<mutex> __lk(*__mut);
__lock.unlock();
unique_ptr<_Lock, __lock_external> __(&__lock);
lock_guard<unique_lock<mutex> > _(__lk, adopt_lock);
__cv_.wait(__lk);
}
template <class _Lock, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
void
condition_variable_any::wait(_Lock& __lock, _Predicate __pred)
{
while (!__pred())
wait(__lock);
}
template <class _Lock, class _Clock, class _Duration>
cv_status
condition_variable_any::wait_until(_Lock& __lock,
const chrono::time_point<_Clock, _Duration>& __t)
{
shared_ptr<mutex> __mut = __mut_;
unique_lock<mutex> __lk(*__mut);
__lock.unlock();
unique_ptr<_Lock, __lock_external> __(&__lock);
lock_guard<unique_lock<mutex> > _(__lk, adopt_lock);
return __cv_.wait_until(__lk, __t);
}
template <class _Lock, class _Clock, class _Duration, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
bool
condition_variable_any::wait_until(_Lock& __lock,
const chrono::time_point<_Clock, _Duration>& __t,
_Predicate __pred)
{
while (!__pred())
if (wait_until(__lock, __t) == cv_status::timeout)
return __pred();
return true;
}
template <class _Lock, class _Rep, class _Period>
inline _LIBCPP_INLINE_VISIBILITY
cv_status
condition_variable_any::wait_for(_Lock& __lock,
const chrono::duration<_Rep, _Period>& __d)
{
return wait_until(__lock, chrono::steady_clock::now() + __d);
}
template <class _Lock, class _Rep, class _Period, class _Predicate>
inline _LIBCPP_INLINE_VISIBILITY
bool
condition_variable_any::wait_for(_Lock& __lock,
const chrono::duration<_Rep, _Period>& __d,
_Predicate __pred)
{
return wait_until(__lock, chrono::steady_clock::now() + __d,
_VSTD::move(__pred));
}
_LIBCPP_VISIBLE
void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk);
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_CONDITION_VARIABLE