summaryrefslogtreecommitdiff
path: root/apt-pkg/deb
diff options
context:
space:
mode:
Diffstat (limited to 'apt-pkg/deb')
-rw-r--r--apt-pkg/deb/debsystem.cc50
-rw-r--r--apt-pkg/deb/debsystem.h5
2 files changed, 47 insertions, 8 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)
diff --git a/apt-pkg/deb/debsystem.h b/apt-pkg/deb/debsystem.h
index a331af351..2e5a8550c 100644
--- a/apt-pkg/deb/debsystem.h
+++ b/apt-pkg/deb/debsystem.h
@@ -27,8 +27,7 @@ class debSystem : public pkgSystem
APT_HIDDEN bool CheckUpdates();
public:
-
- virtual bool Lock() APT_OVERRIDE;
+ virtual bool Lock(OpProgress *const Progress) APT_OVERRIDE;
virtual bool UnLock(bool NoErrors = false) APT_OVERRIDE;
virtual pkgPackageManager *CreatePM(pkgDepCache *Cache) const APT_OVERRIDE;
virtual bool Initialize(Configuration &Cnf) APT_OVERRIDE;
@@ -48,7 +47,7 @@ class debSystem : public pkgSystem
bool MultiArchSupported() const override;
std::vector<std::string> ArchitecturesSupported() const override;
- bool LockInner() override;
+ bool LockInner(OpProgress *const Progress, int timeoutSec) override;
bool UnLockInner(bool NoErrors=false) override;
bool IsLocked() override;
};