diff --git a/src/format/Format.cc b/src/format/Format.cc index bd0faf69471..faf1814aa06 100644 --- a/src/format/Format.cc +++ b/src/format/Format.cc @@ -640,11 +640,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS const auto &timer = (!al->hier.totalPeeringTime.ran() && al->request) ? al->request->hier.totalPeeringTime : al->hier.totalPeeringTime; if (timer.ran()) { - using namespace std::chrono_literals; - const auto duration = timer.total(); - outtv.tv_sec = std::chrono::duration_cast(duration).count(); - const auto totalUsec = std::chrono::duration_cast(duration); - outtv.tv_usec = (totalUsec % std::chrono::microseconds(1s)).count(); + outtv = ToTimeval(timer.total()); doMsec = 1; } } diff --git a/src/icmp/pinger.cc b/src/icmp/pinger.cc index 6d0952e2b97..8f5f9e0cad7 100644 --- a/src/icmp/pinger.cc +++ b/src/icmp/pinger.cc @@ -191,9 +191,7 @@ main(int, char **) #endif for (;;) { - struct timeval tv; - tv.tv_sec = std::chrono::seconds(PingerTimeout).count(); - tv.tv_usec = 0; + auto tv = ToTimeval(PingerTimeout); FD_ZERO(&R); if (icmp4_worker >= 0) { FD_SET(icmp4_worker, &R); diff --git a/src/time/gadgets.cc b/src/time/gadgets.cc index d542dfacd4f..865d545ba33 100644 --- a/src/time/gadgets.cc +++ b/src/time/gadgets.cc @@ -25,8 +25,7 @@ getCurrentTime() using namespace std::chrono; const auto now = system_clock::now().time_since_epoch(); - current_time.tv_sec = duration_cast(now).count(); - current_time.tv_usec = duration_cast(now).count() % 1000000; + current_time = ToTimeval(now); current_dtime = (double) current_time.tv_sec + (double) current_time.tv_usec / 1000000.0; diff --git a/src/time/gadgets.h b/src/time/gadgets.h index a3e60bf4232..7cd189487b4 100644 --- a/src/time/gadgets.h +++ b/src/time/gadgets.h @@ -9,6 +9,7 @@ #ifndef SQUID_SRC_TIME_GADGETS_H #define SQUID_SRC_TIME_GADGETS_H +#include #include #include @@ -95,6 +96,22 @@ inline long int tvToMsec(struct timeval &t) return t.tv_sec * 1000 + t.tv_usec / 1000; } +/// Converts std::chrono::duration to timeval. Input values up to ~68 years do +/// not overflow timeval even if timeval::tv_sec (i.e. time_t) has only 32 bits. +/// Input values with precision higher than microseconds decrease precision +/// because timeval::tv_usec stores microseconds. +template +timeval +ToTimeval(const Duration duration) +{ + using namespace std::chrono_literals; + timeval out; + out.tv_sec = std::chrono::duration_cast(duration).count(); + const auto totalUsec = std::chrono::duration_cast(duration); + out.tv_usec = (totalUsec % std::chrono::microseconds(1s)).count(); + return out; +} + /// prints . std::ostream &operator <<(std::ostream &, const timeval &);