diff options
author | Julian Andres Klode <jak@debian.org> | 2020-02-26 20:28:47 +0000 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2020-02-26 20:28:47 +0000 |
commit | b71b6802fe64723117bce6d91495a8af98ac528a (patch) | |
tree | ebb655eb7496799009b672c39799f670a596eb3e /apt-pkg/deb/debsystem.cc | |
parent | be22f24669bb6731b5835dc0e1b459d821683a9c (diff) | |
parent | 93e1565796b61eb44bec39f50e09a34cbe090178 (diff) |
Merge branch 'pu/wait-lock' into 'master'
Pu/wait lock
See merge request apt-team/apt!109
Diffstat (limited to 'apt-pkg/deb/debsystem.cc')
-rw-r--r-- | apt-pkg/deb/debsystem.cc | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/apt-pkg/deb/debsystem.cc b/apt-pkg/deb/debsystem.cc index 225761e9d..da7ae2e42 100644 --- a/apt-pkg/deb/debsystem.cc +++ b/apt-pkg/deb/debsystem.cc @@ -19,8 +19,10 @@ #include <apt-pkg/error.h> #include <apt-pkg/fileutl.h> #include <apt-pkg/pkgcache.h> +#include <apt-pkg/progress.h> #include <algorithm> +#include <sstream> #include <string> #include <vector> @@ -75,7 +77,42 @@ debSystem::~debSystem() // --------------------------------------------------------------------- /* This mirrors the operations dpkg does when it starts up. Note the checking of the updates directory. */ -bool debSystem::Lock() +static int GetLockMaybeWait(std::string const &file, OpProgress *Progress, int &timeoutSec) +{ + int fd = -1; + if (timeoutSec == 0 || Progress == nullptr) + return GetLock(file); + + if (_config->FindB("Debug::Locking", false)) + std::cerr << "Lock: " << file << " wait " << timeoutSec << std::endl; + + for (int i = 0; timeoutSec < 0 || i < timeoutSec; i++) + { + _error->PushToStack(); + fd = GetLock(file); + if (fd != -1 || errno == EPERM) + { + if (timeoutSec > 0) + timeoutSec -= i; + _error->MergeWithStack(); + return fd; + } + std::string poppedError; + std::string completeError; + _error->PopMessage(poppedError); + _error->RevertToStack(); + + strprintf(completeError, _("Waiting for cache lock (%s)"), poppedError.c_str()); + sleep(1); + Progress->OverallProgress(i, timeoutSec, 0, completeError); + } + + if (timeoutSec > 0) + timeoutSec = 1; + return fd; +} + +bool debSystem::Lock(OpProgress *const Progress) { // Disable file locking if (_config->FindB("Debug::NoLocking",false) == true || d->LockCount > 0) @@ -84,10 +121,12 @@ bool debSystem::Lock() return true; } + // This will count downwards. + int lockTimeOutSec = _config->FindI("DPkg::Lock::Timeout", 0); // Create the lockfile string AdminDir = flNotFile(_config->FindFile("Dir::State::status")); string FrontendLockFile = AdminDir + "lock-frontend"; - d->FrontendLockFD = GetLock(FrontendLockFile); + d->FrontendLockFD = GetLockMaybeWait(FrontendLockFile, Progress, lockTimeOutSec); if (d->FrontendLockFD == -1) { if (errno == EACCES || errno == EAGAIN) @@ -97,7 +136,7 @@ bool debSystem::Lock() return _error->Error(_("Unable to acquire the dpkg frontend lock (%s), " "are you root?"),FrontendLockFile.c_str()); } - if (LockInner() == false) + if (LockInner(Progress, lockTimeOutSec) == false) { close(d->FrontendLockFD); return false; @@ -126,9 +165,10 @@ bool debSystem::Lock() return true; } -bool debSystem::LockInner() { +bool debSystem::LockInner(OpProgress *const Progress, int timeOutSec) +{ string AdminDir = flNotFile(_config->FindFile("Dir::State::status")); - d->LockFD = GetLock(AdminDir + "lock"); + d->LockFD = GetLockMaybeWait(AdminDir + "lock", Progress, timeOutSec); if (d->LockFD == -1) { if (errno == EACCES || errno == EAGAIN) |