Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce is_clock_v in Clause 32 [thread] headers #1687

Merged
merged 4 commits into from
Mar 2, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions stl/inc/condition_variable
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,18 @@ public:
template <class _Lock, class _Clock, class _Duration>
cv_status wait_until(_Lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// wait until time point
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
return wait_for(_Lck, _Abs_time - _Clock::now());
}

template <class _Lock, class _Clock, class _Duration, class _Predicate>
bool wait_until(_Lock& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate _Pred) {
// wait for signal with timeout and check predicate
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
while (!_Pred()) {
if (wait_until(_Lck, _Abs_time) == cv_status::timeout) {
return _Pred();
Expand Down Expand Up @@ -193,6 +199,9 @@ public:
template <class _Lock, class _Clock, class _Duration, class _Predicate>
bool wait_until(
_Lock& _Lck, stop_token _Stoken, const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate _Pred) {
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
StephanTLavavej marked this conversation as resolved.
Show resolved Hide resolved
stop_callback<_Cv_any_notify_all> _Cb{_Stoken, this};
for (;;) {
if (_Pred()) {
Expand Down
3 changes: 3 additions & 0 deletions stl/inc/future
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,9 @@ public:

template <class _Clock, class _Dur>
future_status wait_until(const chrono::time_point<_Clock, _Dur>& _Abs_time) const { // wait until time point
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
if (!valid()) {
_Throw_future_error(make_error_code(future_errc::no_state));
}
Expand Down
30 changes: 25 additions & 5 deletions stl/inc/mutex
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,12 @@ public:

template <class _Clock, class _Duration>
_NODISCARD_CTOR unique_lock(_Mutex& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time)
: _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock_until(_Abs_time)) {} // construct and lock with timeout
: _Pmtx(_STD addressof(_Mtx)), _Owns(_Pmtx->try_lock_until(_Abs_time)) {
// construct and lock with timeout
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
}

_NODISCARD_CTOR unique_lock(_Mutex& _Mtx, const xtime* _Abs_time)
: _Pmtx(_STD addressof(_Mtx)), _Owns(false) { // try to lock until _Abs_time
Expand Down Expand Up @@ -209,6 +214,9 @@ public:

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
_Validate();
_Owns = _Pmtx->try_lock_until(_Abs_time);
return _Owns;
Expand Down Expand Up @@ -635,6 +643,9 @@ public:
template <class _Clock, class _Duration>
cv_status wait_until(unique_lock<mutex>& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// wait until time point
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
for (;;) {
const auto _Now = _Clock::now();
if (_Abs_time <= _Now) {
Expand All @@ -654,6 +665,9 @@ public:
bool wait_until(
unique_lock<mutex>& _Lck, const chrono::time_point<_Clock, _Duration>& _Abs_time, _Predicate _Pred) {
// wait for signal with timeout and check predicate
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
return _Wait_until1(_Lck, _Abs_time, _Pred);
}

Expand Down Expand Up @@ -792,8 +806,11 @@ public:
}

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex with timeout
_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// try to lock the mutex with timeout
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
return _Try_lock_until(_Abs_time);
}

Expand Down Expand Up @@ -903,8 +920,11 @@ public:
}

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex with timeout
_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// try to lock the mutex with timeout
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
return _Try_lock_until(_Abs_time);
}

Expand Down
2 changes: 2 additions & 0 deletions stl/inc/semaphore
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public:

template <class _Clock, class _Duration>
_NODISCARD bool try_acquire_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
ptrdiff_t _Current = _Counter.load(memory_order_relaxed);
for (;;) {
while (_Current == 0) {
Expand Down Expand Up @@ -274,6 +275,7 @@ public:

template <class _Clock, class _Duration>
_NODISCARD bool try_acquire_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
for (;;) {
// "happens after release" ordering is provided by this exchange, so loads and waits can be relaxed
// TRANSITION, GH-1133: should be memory_order_acquire
Expand Down
32 changes: 22 additions & 10 deletions stl/inc/shared_mutex
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,11 @@ public:
}

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock until time point
_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// try to lock until time point
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
auto _Not_writing = [this] { return !_Writing; };
auto _Zero_readers = [this] { return _Readers == 0; };
unique_lock<mutex> _Lock(_Mymtx);
Expand Down Expand Up @@ -166,8 +169,8 @@ public:
}

template <class _Rep, class _Period>
_NODISCARD bool try_lock_shared_for(
const chrono::duration<_Rep, _Period>& _Rel_time) { // try to lock non-exclusive for relative time
_NODISCARD bool try_lock_shared_for(const chrono::duration<_Rep, _Period>& _Rel_time) {
// try to lock non-exclusive for relative time
return try_lock_shared_until(_To_absolute_time(_Rel_time));
}

Expand All @@ -186,8 +189,11 @@ public:
}

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_shared_until(
const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock non-exclusive until absolute time
_NODISCARD bool try_lock_shared_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// try to lock non-exclusive until absolute time
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
return _Try_lock_shared_until(_Abs_time);
}

Expand Down Expand Up @@ -257,6 +263,9 @@ public:
_NODISCARD_CTOR shared_lock(mutex_type& _Mtx, const chrono::time_point<_Clock, _Duration>& _Abs_time)
: _Pmtx(_STD addressof(_Mtx)), _Owns(_Mtx.try_lock_shared_until(_Abs_time)) {
// construct with mutex and try to lock until absolute time
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
}

~shared_lock() noexcept {
Expand Down Expand Up @@ -298,16 +307,19 @@ public:
}

template <class _Rep, class _Period>
_NODISCARD bool try_lock_for(
const chrono::duration<_Rep, _Period>& _Rel_time) { // try to lock the mutex for _Rel_time
_NODISCARD bool try_lock_for(const chrono::duration<_Rep, _Period>& _Rel_time) {
// try to lock the mutex for _Rel_time
_Validate();
_Owns = _Pmtx->try_lock_shared_for(_Rel_time);
return _Owns;
}

template <class _Clock, class _Duration>
_NODISCARD bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _Abs_time) { // try to lock the mutex until _Abs_time
_NODISCARD bool try_lock_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
// try to lock the mutex until _Abs_time
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
_Validate();
_Owns = _Pmtx->try_lock_shared_until(_Abs_time);
return _Owns;
Expand Down
3 changes: 3 additions & 0 deletions stl/inc/thread
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ namespace this_thread {

template <class _Clock, class _Duration>
void sleep_until(const chrono::time_point<_Clock, _Duration>& _Abs_time) {
#if _HAS_CXX20
static_assert(chrono::is_clock_v<_Clock>, "Clock type required");
#endif // _HAS_CXX20
for (;;) {
const auto _Now = _Clock::now();
if (_Abs_time <= _Now) {
Expand Down