diff options
author | Julian Andres Klode <julian.klode@canonical.com> | 2021-07-27 16:40:38 +0200 |
---|---|---|
committer | Julian Andres Klode <julian.klode@canonical.com> | 2021-07-28 13:08:35 +0200 |
commit | 48a7ece8d0e065240153a85089f544383e16137f (patch) | |
tree | dd483a370a4535aa550ed39e006ab351f1382630 | |
parent | 7e88def0548a92112f8295686c2a12379e4028be (diff) |
Convert to monotonic clock
This yields more accurate delays and avoids issues with clock
skew.
-rw-r--r-- | apt-pkg/acquire-item.cc | 6 | ||||
-rw-r--r-- | apt-pkg/acquire-item.h | 5 | ||||
-rw-r--r-- | apt-pkg/acquire-worker.cc | 5 | ||||
-rw-r--r-- | apt-pkg/acquire.cc | 32 | ||||
-rw-r--r-- | apt-pkg/acquire.h | 7 |
5 files changed, 33 insertions, 22 deletions
diff --git a/apt-pkg/acquire-item.cc b/apt-pkg/acquire-item.cc index 20d80edc0..eb8053feb 100644 --- a/apt-pkg/acquire-item.cc +++ b/apt-pkg/acquire-item.cc @@ -290,7 +290,7 @@ public: std::vector<std::string> BadAlternativeSites; std::vector<std::string> PastRedirections; std::unordered_map<std::string, std::string> CustomFields; - time_t FetchAfter = 0; + time_point FetchAfter = {}; Private() { @@ -1121,11 +1121,11 @@ std::string pkgAcquire::Item::HashSum() const /*{{{*/ return hs != NULL ? hs->toStr() : ""; } /*}}}*/ -void pkgAcquire::Item::FetchAfter(time_t FetchAfter) /*{{{*/ +void pkgAcquire::Item::FetchAfter(time_point FetchAfter) /*{{{*/ { d->FetchAfter = FetchAfter; } -time_t pkgAcquire::Item::FetchAfter() +pkgAcquire::time_point pkgAcquire::Item::FetchAfter() { return d->FetchAfter; } diff --git a/apt-pkg/acquire-item.h b/apt-pkg/acquire-item.h index 33106226f..22da9815d 100644 --- a/apt-pkg/acquire-item.h +++ b/apt-pkg/acquire-item.h @@ -301,8 +301,9 @@ class APT_PUBLIC pkgAcquire::Item : public WeakPointable /*{{{*/ /** \brief The priority of the item, used for queuing */ int APT_HIDDEN Priority(); - void APT_HIDDEN FetchAfter(time_t FetchAfter); - time_t APT_HIDDEN FetchAfter(); + /** \brief internal clock definitions to avoid typing all that all over the place */ + void APT_HIDDEN FetchAfter(time_point FetchAfter); + time_point APT_HIDDEN FetchAfter(); protected: /** \brief The acquire object with which this item is associated. */ diff --git a/apt-pkg/acquire-worker.cc b/apt-pkg/acquire-worker.cc index 5272ae0cb..7be51d114 100644 --- a/apt-pkg/acquire-worker.cc +++ b/apt-pkg/acquire-worker.cc @@ -632,7 +632,7 @@ void pkgAcquire::Worker::HandleFailure(std::vector<pkgAcquire::Item *> const &It pkgAcquire::MethodConfig *const Config, pkgAcquireStatus *const Log, std::string const &Message, bool const errTransient, bool const errAuthErr) { - time_t currentTime = time(nullptr); + auto currentTime = clock::now(); for (auto const Owner : ItmOwners) { std::string NewURI; @@ -644,7 +644,8 @@ void pkgAcquire::Worker::HandleFailure(std::vector<pkgAcquire::Item *> const &It if (_config->FindB("Acquire::Retries::Delay", true)) { auto Iter = _config->FindI("Acquire::Retries", 3) - Owner->Retries - 1; - Owner->FetchAfter(currentTime + (1 << Iter)); + auto Dur = std::chrono::seconds(1 << Iter); + Owner->FetchAfter(currentTime + Dur); } else { diff --git a/apt-pkg/acquire.cc b/apt-pkg/acquire.cc index 5b3d5906b..e97f5e6f3 100644 --- a/apt-pkg/acquire.cc +++ b/apt-pkg/acquire.cc @@ -53,6 +53,14 @@ using namespace std; +// helper to convert time_point to a timeval +static struct timeval SteadyDurationToTimeVal(std::chrono::steady_clock::duration Time) +{ + auto const Time_sec = std::chrono::duration_cast<std::chrono::seconds>(Time); + auto const Time_usec = std::chrono::duration_cast<std::chrono::microseconds>(Time - Time_sec); + return {Time_sec.count(), Time_usec.count()}; +} + std::string pkgAcquire::URIEncode(std::string const &part) /*{{{*/ { // The "+" is encoded as a workaround for an S3 bug (LP#1003633 and LP#1086997) @@ -717,8 +725,8 @@ pkgAcquire::RunResult pkgAcquire::Run(int PulseIntervall) SetFds(Highest,&RFds,&WFds); // Shorten the select() cycle in case we have items about to become ready - time_t now = time(nullptr); - time_t fetchAfter = 0; + auto now = clock::now(); + auto fetchAfter = time_point{}; for (Queue *I = Queues; I != nullptr; I = I->Next) { if (I->Items == nullptr) @@ -726,7 +734,7 @@ pkgAcquire::RunResult pkgAcquire::Run(int PulseIntervall) auto f = I->Items->GetFetchAfter(); - if (f == 0 || I->Items->Owner->Status != pkgAcquire::Item::StatIdle) + if (f == time_point() || I->Items->Owner->Status != pkgAcquire::Item::StatIdle) continue; if (f <= now) @@ -735,16 +743,15 @@ pkgAcquire::RunResult pkgAcquire::Run(int PulseIntervall) fetchAfter = now; // need to time out in select() below assert(I->Items->Owner->Status != pkgAcquire::Item::StatIdle); } - else if (f < fetchAfter || fetchAfter == 0) + else if (f < fetchAfter || fetchAfter == time_point{}) { fetchAfter = f; } } - if (fetchAfter && (fetchAfter - now) < (tv.tv_sec + tv.tv_usec / 1e6)) + if (fetchAfter != time_point{} && (fetchAfter - now) < std::chrono::seconds(tv.tv_sec) + std::chrono::microseconds(tv.tv_usec)) { - tv.tv_sec = fetchAfter - now; - tv.tv_usec = 0; + tv = SteadyDurationToTimeVal(fetchAfter - now); } int Res; @@ -1191,7 +1198,7 @@ bool pkgAcquire::Queue::Cycle() // Look for a queable item QItem *I = Items; int ActivePriority = 0; - time_t currentTime = time(nullptr); + auto currentTime = clock::now(); while (PipeDepth < static_cast<decltype(PipeDepth)>(MaxPipeDepth)) { for (; I != 0; I = I->Next) { @@ -1281,9 +1288,9 @@ APT_PURE int pkgAcquire::Queue::QItem::GetPriority() const /*{{{*/ return Priority; } /*}}}*/ -APT_PURE time_t pkgAcquire::Queue::QItem::GetFetchAfter() const /*{{{*/ +APT_PURE pkgAcquire::time_point pkgAcquire::Queue::QItem::GetFetchAfter() const /*{{{*/ { - time_t FetchAfter = 0; + time_point FetchAfter{}; for (auto const &O : Owners) FetchAfter = std::max(FetchAfter, O->FetchAfter()); @@ -1347,10 +1354,7 @@ pkgAcquireStatus::pkgAcquireStatus() : d(NULL), Percent(-1), Update(true), MoreP as well as the current CPS estimate. */ static struct timeval GetTimevalFromSteadyClock() { - auto const Time = std::chrono::steady_clock::now().time_since_epoch(); - auto const Time_sec = std::chrono::duration_cast<std::chrono::seconds>(Time); - auto const Time_usec = std::chrono::duration_cast<std::chrono::microseconds>(Time - Time_sec); - return { Time_sec.count(), Time_usec.count() }; + return SteadyDurationToTimeVal(std::chrono::steady_clock::now().time_since_epoch()); } bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) { diff --git a/apt-pkg/acquire.h b/apt-pkg/acquire.h index 303554041..09bb408bc 100644 --- a/apt-pkg/acquire.h +++ b/apt-pkg/acquire.h @@ -69,6 +69,7 @@ #include <apt-pkg/macros.h> #include <apt-pkg/weakptr.h> +#include <chrono> #include <string> #include <vector> @@ -92,6 +93,10 @@ class metaIndex; class APT_PUBLIC pkgAcquire { private: + /** \brief The monotonic clock used by the Acquire system */ + using clock = std::chrono::steady_clock; + /** \brief Time point on our monotonic clock */ + using time_point = std::chrono::time_point<clock>; /** \brief FD of the Lock file we acquire in Setup (if any) */ int LockFD; /** \brief dpointer placeholder (for later in case we need it) */ @@ -459,7 +464,7 @@ class APT_PUBLIC pkgAcquire::Queue /** @return the maximum priority of this item */ int APT_HIDDEN GetPriority() const; /** @return the maximum time to fetch this item at */ - time_t APT_HIDDEN GetFetchAfter() const; + time_point APT_HIDDEN GetFetchAfter() const; }; /** \brief The name of this queue. */ |