diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2009-02-16 09:24:20 +0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2009-02-16 09:24:20 +0000 |
commit | 824b154ce82a76bfc604b3084b18e06af4e3d007 (patch) | |
tree | 709a67a7a4fdf2077c05e1f275eb180ec8ec7602 /src | |
parent | 2ef579d1aa62501d59957783665f997e3c6f475b (diff) |
* Release output locks as soon as possible, not when the destructor of
the DerivationGoal runs. Otherwise, if a goal is a top-level goal,
then the lock won't be released until nix-store finishes. With
--keep-going and lots of top-level goals, it's possible to run out
of file descriptors (this happened sometimes in the build farm for
Nixpkgs). Also, for failed derivation, it won't be possible to
build it again until the lock is released.
* Idem for locks on build users: these weren't released in a timely
manner for failed top-level derivation goals. So if there were more
than (say) 10 such failed builds, you would get an error about
having run out of build users.
Diffstat (limited to 'src')
-rw-r--r-- | src/libstore/build.cc | 5 | ||||
-rw-r--r-- | src/libstore/pathlocks.cc | 8 | ||||
-rw-r--r-- | src/libstore/pathlocks.hh | 1 |
3 files changed, 14 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index d44dcf0ff..5f1eb3415 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1023,6 +1023,8 @@ void DerivationGoal::tryToBuild() } catch (BuildError & e) { printMsg(lvlError, e.msg()); + outputLocks.unlock(); + buildUser.release(); if (printBuildTrace) { if (usingBuildHook) printMsg(lvlError, format("@ hook-failed %1% %2% %3% %4%") @@ -1130,6 +1132,8 @@ void DerivationGoal::buildDone() } catch (BuildError & e) { printMsg(lvlError, e.msg()); + outputLocks.unlock(); + buildUser.release(); if (printBuildTrace) { /* When using a build hook, the hook will return a remote build failure using exit code 100. Anything @@ -2068,6 +2072,7 @@ void DerivationGoal::computeClosure() create new lock files with the same names as the old (unlinked) lock files. */ outputLocks.setDeletion(true); + outputLocks.unlock(); } diff --git a/src/libstore/pathlocks.cc b/src/libstore/pathlocks.cc index df1f0b1e3..f8753bcb6 100644 --- a/src/libstore/pathlocks.cc +++ b/src/libstore/pathlocks.cc @@ -204,6 +204,12 @@ void PathLocks::lockPaths(const PathSet & _paths, const string & waitMsg) PathLocks::~PathLocks() { + unlock(); +} + + +void PathLocks::unlock() +{ for (list<FDPair>::iterator i = fds.begin(); i != fds.end(); i++) { if (deletePaths) deleteLockFilePreClose(i->second, i->first); @@ -216,6 +222,8 @@ PathLocks::~PathLocks() debug(format("lock released on `%1%'") % i->second); } + + fds.clear(); } diff --git a/src/libstore/pathlocks.hh b/src/libstore/pathlocks.hh index 8b4100028..9898b497b 100644 --- a/src/libstore/pathlocks.hh +++ b/src/libstore/pathlocks.hh @@ -36,6 +36,7 @@ public: void lockPaths(const PathSet & _paths, const string & waitMsg = ""); ~PathLocks(); + void unlock(); void setDeletion(bool deletePaths); }; |