mirror of
https://github.com/NixOS/nix
synced 2025-07-03 06:11:46 +02:00
* 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'.
This commit is contained in:
parent
9df93f30bd
commit
545145cd58
5 changed files with 151 additions and 30 deletions
48
src/pathlocks.cc
Normal file
48
src/pathlocks.cc
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue