On 13/11/20 21:12 +0000, Jonathan Wakely wrote:
On 13/11/20 20:29 +0000, Mike Crowe via Libstdc++ wrote:
On Friday 13 November 2020 at 17:25:22 +0000, Jonathan Wakely wrote:
+  // Return the relative duration from (now_s + now_ns) to (abs_s + abs_ns)
+  // as a timespec.
+  struct timespec
+  relative_timespec(chrono::seconds abs_s, chrono::nanoseconds abs_ns,
+                   time_t now_s, long now_ns)
+  {
+    struct timespec rt;
+
+    // Did we already time out?
+    if (now_s > abs_s.count())
+      {
+       rt.tv_sec = -1;
+       return rt;
+      }
+
+    auto rel_s = abs_s.count() - now_s;
+
+    // Avoid overflows
+    if (rel_s > __gnu_cxx::__int_traits<time_t>::__max)
+      rel_s = __gnu_cxx::__int_traits<time_t>::__max;
+    else if (rel_s < __gnu_cxx::__int_traits<time_t>::__min)
+      rel_s = __gnu_cxx::__int_traits<time_t>::__min;

I may be missing something, but if the line above executes...

+
+    // Convert the absolute timeout value to a relative timeout
+    rt.tv_sec = rel_s;
+    rt.tv_nsec = abs_ns.count() - now_ns;
+    if (rt.tv_nsec < 0)
+      {
+       rt.tv_nsec += 1000000000;
+       --rt.tv_sec;

...and so does this line above, then I think that we'll end up
underflowing. (Presumably rt.tv_sec will wrap round to being some time in
2038 on most 32-bit targets.)

Ugh.

I'm currently trying to persuade myself that this can actually happen and
if so work out how to come up with a test case for it.

Maybe something like:

auto d = chrono::floor<chrono::seconds>(system_clock::now().time_since_epoch() 
- seconds(INT_MAX + 2LL));
fut.wait_until(system_clock::time_point(d));

This will create a sys_time with a value that is slightly more than
INT_MAX seconds before the current time, with a zero nanoseconds

Ah, but such a time will never reach the overflow because the first
thing that the new relative_timespec function does is:

     if (now_s > abs_s.count())
       {
         rt.tv_sec = -1;
         return rt;
       }

So in fact we can never have a negative rel_s anyway.

Reply via email to