From 545145cd582cd80b857760ec11bb5a91b6271506 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 1 Aug 2003 14:11:19 +0000 Subject: * normaliseFState() now locks all output paths prior to building, thus ensuring that simultaneous invocations of Nix don't clobber each other's builds. * Fixed a bug in `make install'. --- src/pathlocks.cc | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/pathlocks.cc (limited to 'src/pathlocks.cc') diff --git a/src/pathlocks.cc b/src/pathlocks.cc new file mode 100644 index 000000000000..ac53dc6437d0 --- /dev/null +++ b/src/pathlocks.cc @@ -0,0 +1,48 @@ +#include + +#include "pathlocks.hh" + + +PathLocks::PathLocks(const Strings & _paths) +{ + /* 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. */ + Strings paths(_paths); + paths.sort(); + + /* Acquire the lock for each path. */ + for (Strings::iterator i = paths.begin(); i != paths.end(); i++) { + string path = *i; + string lockPath = path + ".lock"; + + debug(format("locking path `%1%'") % path); + + /* Open/create the lock file. */ + int fd = open(lockPath.c_str(), O_WRONLY | O_CREAT, 0666); + if (fd == -1) + throw SysError(format("opening lock file `%1%'") % lockPath); + + fds.push_back(fd); + + /* Lock it. */ + struct flock lock; + lock.l_type = F_WRLCK; /* exclusive lock */ + lock.l_whence = SEEK_SET; + lock.l_start = 0; + lock.l_len = 0; /* entire file */ + + while (fcntl(fd, F_SETLKW, &lock) == -1) + if (errno != EINTR) + throw SysError(format("acquiring lock on `%1%'") % lockPath); + } +} + + +PathLocks::~PathLocks() +{ + for (list::iterator i = fds.begin(); i != fds.end(); i++) + close(*i); +} -- cgit 1.4.1