diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-08-01 14:11:19 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2003-08-01 14:11:19 +0000 |
commit | 545145cd582cd80b857760ec11bb5a91b6271506 (patch) | |
tree | e992edea7a634ed268ac10444add5dcfac6a4f05 /src/pathlocks.cc | |
parent | 9df93f30bda81ffa3cf040c146347e02d3a56666 (diff) |
* 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'.
Diffstat (limited to 'src/pathlocks.cc')
-rw-r--r-- | src/pathlocks.cc | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/pathlocks.cc b/src/pathlocks.cc new file mode 100644 index 000000000..ac53dc643 --- /dev/null +++ b/src/pathlocks.cc @@ -0,0 +1,48 @@ +#include <fcntl.h> + +#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<int>::iterator i = fds.begin(); i != fds.end(); i++) + close(*i); +} |