summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <julian.klode@canonical.com>2021-07-27 16:40:38 +0200
committerJulian Andres Klode <julian.klode@canonical.com>2021-07-28 13:08:35 +0200
commit48a7ece8d0e065240153a85089f544383e16137f (patch)
treedd483a370a4535aa550ed39e006ab351f1382630
parent7e88def0548a92112f8295686c2a12379e4028be (diff)
Convert to monotonic clock
This yields more accurate delays and avoids issues with clock skew.
-rw-r--r--apt-pkg/acquire-item.cc6
-rw-r--r--apt-pkg/acquire-item.h5
-rw-r--r--apt-pkg/acquire-worker.cc5
-rw-r--r--apt-pkg/acquire.cc32
-rw-r--r--apt-pkg/acquire.h7
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. */