summary refs log tree commit diff
path: root/src/libstore/pathlocks.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/pathlocks.cc')
-rw-r--r--src/libstore/pathlocks.cc199
1 files changed, 0 insertions, 199 deletions
diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc
deleted file mode 100644
index b858ed238d..0000000000
--- a/src/libstore/pathlocks.cc
+++ /dev/null
@@ -1,199 +0,0 @@
-#include "pathlocks.hh"
-#include "util.hh"
-
-#include <cerrno>
-#include <cstdlib>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-namespace nix {
-
-
-int openLockFile(const Path & path, bool create)
-{
-    AutoCloseFD fd;
-
-    fd = open(path.c_str(), O_RDWR | (create ? O_CREAT : 0), 0600);
-    if (fd == -1 && (create || errno != ENOENT))
-        throw SysError(format("opening lock file `%1%'") % path);
-
-    closeOnExec(fd);
-
-    return fd.borrow();
-}
-
-
-void deleteLockFile(const Path & path, int fd)
-{
-    /* Get rid of the lock file.  Have to be careful not to introduce
-       races.  Write a (meaningless) token to the file to indicate to
-       other processes waiting on this lock that the lock is stale
-       (deleted). */
-    unlink(path.c_str());
-    writeFull(fd, (const unsigned char *) "d", 1);
-    /* Note that the result of unlink() is ignored; removing the lock
-       file is an optimisation, not a necessity. */
-}
-
-
-bool lockFile(int fd, LockType lockType, bool wait)
-{
-    struct flock lock;
-    if (lockType == ltRead) lock.l_type = F_RDLCK;
-    else if (lockType == ltWrite) lock.l_type = F_WRLCK;
-    else if (lockType == ltNone) lock.l_type = F_UNLCK;
-    else abort();
-    lock.l_whence = SEEK_SET;
-    lock.l_start = 0;
-    lock.l_len = 0; /* entire file */
-
-    if (wait) {
-        while (fcntl(fd, F_SETLKW, &lock) != 0) {
-            checkInterrupt();
-            if (errno != EINTR)
-                throw SysError(format("acquiring/releasing lock"));
-        }
-    } else {
-        while (fcntl(fd, F_SETLK, &lock) != 0) {
-            checkInterrupt();
-            if (errno == EACCES || errno == EAGAIN) return false;
-            if (errno != EINTR) 
-                throw SysError(format("acquiring/releasing lock"));
-        }
-    }
-
-    return true;
-}
-
-
-/* This enables us to check whether are not already holding a lock on
-   a file ourselves.  POSIX locks (fcntl) suck in this respect: if we
-   close a descriptor, the previous lock will be closed as well.  And
-   there is no way to query whether we already have a lock (F_GETLK
-   only works on locks held by other processes). */
-static StringSet lockedPaths; /* !!! not thread-safe */
-
-
-PathLocks::PathLocks()
-    : deletePaths(false)
-{
-}
-
-
-PathLocks::PathLocks(const PathSet & paths, const string & waitMsg)
-    : deletePaths(false)
-{
-    lockPaths(paths, waitMsg);
-}
-
-
-bool PathLocks::lockPaths(const PathSet & _paths,
-    const string & waitMsg, bool wait)
-{
-    assert(fds.empty());
-    
-    /* Note that `fds' is built incrementally so that the destructor
-       will only release those locks that we have already acquired. */
-
-    /* Sort the paths.  This assures that locks are always acquired in
-       the same order, thus preventing deadlocks. */
-    Paths paths(_paths.begin(), _paths.end());
-    paths.sort();
-    
-    /* Acquire the lock for each path. */
-    foreach (Paths::iterator, i, paths) {
-        checkInterrupt();
-        Path path = *i;
-        Path lockPath = path + ".lock";
-
-        debug(format("locking path `%1%'") % path);
-
-        if (lockedPaths.find(lockPath) != lockedPaths.end())
-            throw Error("deadlock: trying to re-acquire self-held lock");
-
-        AutoCloseFD fd;
-        
-        while (1) {
-
-            /* Open/create the lock file. */
-	    fd = openLockFile(lockPath, true);
-
-            /* Acquire an exclusive lock. */
-            if (!lockFile(fd, ltWrite, false)) {
-                if (wait) {
-                    if (waitMsg != "") printMsg(lvlError, waitMsg);
-                    lockFile(fd, ltWrite, true);
-                } else {
-                    /* Failed to lock this path; release all other
-                       locks. */
-                    unlock();
-                    return false;
-                }
-            }
-
-            debug(format("lock acquired on `%1%'") % lockPath);
-
-            /* Check that the lock file hasn't become stale (i.e.,
-               hasn't been unlinked). */
-            struct stat st;
-            if (fstat(fd, &st) == -1)
-                throw SysError(format("statting lock file `%1%'") % lockPath);
-            if (st.st_size != 0)
-                /* This lock file has been unlinked, so we're holding
-                   a lock on a deleted file.  This means that other
-                   processes may create and acquire a lock on
-                   `lockPath', and proceed.  So we must retry. */
-                debug(format("open lock file `%1%' has become stale") % lockPath);
-            else
-                break;
-        }
-
-        /* Use borrow so that the descriptor isn't closed. */
-        fds.push_back(FDPair(fd.borrow(), lockPath));
-        lockedPaths.insert(lockPath);
-    }
-
-    return true;
-}
-
-
-PathLocks::~PathLocks()
-{
-    unlock();
-}
-
-
-void PathLocks::unlock()
-{
-    foreach (list<FDPair>::iterator, i, fds) {
-        if (deletePaths) deleteLockFile(i->second, i->first);
-
-        lockedPaths.erase(i->second);
-        if (close(i->first) == -1)
-            printMsg(lvlError,
-                format("error (ignored): cannot close lock file on `%1%'") % i->second);
-
-        debug(format("lock released on `%1%'") % i->second);
-    }
-
-    fds.clear();
-}
-
-
-void PathLocks::setDeletion(bool deletePaths)
-{
-    this->deletePaths = deletePaths;
-}
-
-
-bool pathIsLockedByMe(const Path & path)
-{
-    Path lockPath = path + ".lock";
-    return lockedPaths.find(lockPath) != lockedPaths.end();
-}
-
- 
-}