From 5048e7a30059292d39453df204c84be1a98cd59d Mon Sep 17 00:00:00 2001 From: Matt Stephanson Date: Sat, 10 Jun 2023 21:42:16 -0700 Subject: [PATCH 1/3] Fixes bad timeout in wait_until with unsigned rep --- stl/inc/condition_variable | 4 ++- .../GH_000685_condition_variable_any/test.cpp | 35 ++++++++++++++++--- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/stl/inc/condition_variable b/stl/inc/condition_variable index 6f67941c9d..aa6d322761 100644 --- a/stl/inc/condition_variable +++ b/stl/inc/condition_variable @@ -95,7 +95,9 @@ public: #if _HAS_CXX20 static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); #endif // _HAS_CXX20 - return wait_for(_Lck, _Abs_time - _Clock::now()); + const auto _Now = _Clock::now(); + const _Duration _Rel_time = (_Abs_time <= _Now) ? _Duration::zero() : _Abs_time - _Now; + return wait_for(_Lck, _Rel_time); } template diff --git a/tests/std/tests/GH_000685_condition_variable_any/test.cpp b/tests/std/tests/GH_000685_condition_variable_any/test.cpp index 2d32159823..03ebd7023b 100644 --- a/tests/std/tests/GH_000685_condition_variable_any/test.cpp +++ b/tests/std/tests/GH_000685_condition_variable_any/test.cpp @@ -7,8 +7,10 @@ #include #include #include +#include using namespace std; +using namespace std::chrono; namespace { class my_mutex { // user-defined mutex type @@ -31,8 +33,8 @@ namespace { int num_lock = 0; }; - const chrono::nanoseconds interval{20}; - const chrono::nanoseconds zero_dur{0}; + const nanoseconds interval{20}; + const nanoseconds zero_dur{0}; void test_condition_variable_any() { // test wait functions of condition variables condition_variable_any cnd; @@ -46,15 +48,40 @@ namespace { cnd.wait_for(mtx, interval); assert(mtx.num_locks() == 3); - cnd.wait_until(mtx, chrono::steady_clock::now()); + cnd.wait_until(mtx, steady_clock::now()); assert(mtx.num_locks() == 4); - cnd.wait_until(mtx, chrono::steady_clock::now() + interval); + cnd.wait_until(mtx, steady_clock::now() + interval); assert(mtx.num_locks() == 5); } } + + void test_condition_variable_any_already_timed_out() { + using unsigned_duration = duration, system_clock::period>; + const auto right_now = time_point_cast(system_clock::now()); + const auto yesterday = right_now - hours{24}; + assert(yesterday - right_now > system_clock::duration::zero()); // unsigned overflow + + my_mutex m; + condition_variable_any cond; + unique_lock guard(m); + + const auto status = cond.wait_until(m, yesterday); + assert(status == cv_status::timeout); + assert(m.num_locks() == 2); + + assert(cond.wait_until(m, yesterday, []() { return false; }) == false); + assert(m.num_locks() == 3); + +#if _HAS_CXX20 + stop_token token; + assert(cond.wait_until(m, token, yesterday, []() { return false; }) == false); + assert(m.num_locks() == 4); +#endif // _HAS_CXX20 + } } // unnamed namespace int main() { test_condition_variable_any(); + test_condition_variable_any_already_timed_out(); } From 43ae3f44bc66f834f3c5c9010efcd094084775b3 Mon Sep 17 00:00:00 2001 From: Matt Stephanson Date: Sun, 11 Jun 2023 14:38:43 -0700 Subject: [PATCH 2/3] test fix/code review feedback --- stl/inc/condition_variable | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/condition_variable b/stl/inc/condition_variable index aa6d322761..7c1655f3b8 100644 --- a/stl/inc/condition_variable +++ b/stl/inc/condition_variable @@ -95,8 +95,9 @@ public: #if _HAS_CXX20 static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); #endif // _HAS_CXX20 - const auto _Now = _Clock::now(); - const _Duration _Rel_time = (_Abs_time <= _Now) ? _Duration::zero() : _Abs_time - _Now; + using _CommonDuration = common_type_t<_Duration, typename _Clock::duration>; + const auto _Now = _Clock::now(); + const _CommonDuration _Rel_time = (_Abs_time <= _Now) ? _CommonDuration::zero() : _Abs_time - _Now; return wait_for(_Lck, _Rel_time); } From 22bca57a01ff522934a5eca086d14be98129825c Mon Sep 17 00:00:00 2001 From: Matt Stephanson Date: Tue, 13 Jun 2023 10:20:01 -0700 Subject: [PATCH 3/3] more PR feedback --- stl/inc/condition_variable | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/condition_variable b/stl/inc/condition_variable index 7c1655f3b8..70248b5965 100644 --- a/stl/inc/condition_variable +++ b/stl/inc/condition_variable @@ -95,9 +95,9 @@ public: #if _HAS_CXX20 static_assert(chrono::is_clock_v<_Clock>, "Clock type required"); #endif // _HAS_CXX20 - using _CommonDuration = common_type_t<_Duration, typename _Clock::duration>; - const auto _Now = _Clock::now(); - const _CommonDuration _Rel_time = (_Abs_time <= _Now) ? _CommonDuration::zero() : _Abs_time - _Now; + const auto _Now = _Clock::now(); + using _Common_duration = decltype(_Abs_time - _Now); + const _Common_duration _Rel_time = (_Abs_time <= _Now) ? _Common_duration::zero() : _Abs_time - _Now; return wait_for(_Lck, _Rel_time); }