about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2009-02-16T09·24+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2009-02-16T09·24+0000
commit824b154ce82a76bfc604b3084b18e06af4e3d007 (patch)
tree709a67a7a4fdf2077c05e1f275eb180ec8ec7602
parent2ef579d1aa62501d59957783665f997e3c6f475b (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.

-rw-r--r--src/libstore/build.cc5
-rw-r--r--src/libstore/pathlocks.cc8
-rw-r--r--src/libstore/pathlocks.hh1
3 files changed, 14 insertions, 0 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index d44dcf0ff0..5f1eb3415e 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 df1f0b1e38..f8753bcb66 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 8b4100028f..9898b497b9 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);
 };