about summary refs log tree commit diff
path: root/src/libstore
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2004-06-21T09·35+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2004-06-21T09·35+0000
commit3f3a3ae87b3d72d52842d9a2ffe7010f5b0066b9 (patch)
tree5ed7533eb45dbadcf8f2cc339ef15a1410885f10 /src/libstore
parent72c857f0eb923c3126600a5c97bfb30fedd859c1 (diff)
* Acquire a lock on the output path when running a substitute. Also
  delete obstructing invalid paths.

Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/normalise.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/libstore/normalise.cc b/src/libstore/normalise.cc
index bf096bde7fce..937dbc7f9bac 100644
--- a/src/libstore/normalise.cc
+++ b/src/libstore/normalise.cc
@@ -1207,6 +1207,9 @@ private:
     /* The process ID of the builder. */
     pid_t pid;
 
+    /* Lock on the store path. */
+    PathLocks outputLock;
+    
     typedef void (SubstitutionGoal::*GoalState)();
     GoalState state;
 
@@ -1316,6 +1319,23 @@ void SubstitutionGoal::exprRealised()
 
     logPipe.create();
 
+    /* Acquire a lock on the output path. */
+    PathSet lockPath;
+    lockPath.insert(storePath);
+    outputLock.lockPaths(lockPath);
+
+    /* Check again whether the path is invalid. */
+    if (isValidPath(storePath)) {
+        debug(format("store path `%1%' has become valid") % storePath);
+        outputLock.setDeletion(true);
+        amDone();
+        return;
+    }
+
+    /* Remove the (stale) output path if it exists. */
+    if (pathExists(storePath))
+        deletePath(storePath);
+
     /* Fork the substitute program. */
     switch (pid = fork()) {
         
@@ -1425,6 +1445,8 @@ void SubstitutionGoal::finished()
     registerValidPath(txn, storePath);
     txn.commit();
 
+    outputLock.setDeletion(true);
+    
     amDone();
 }