about summary refs log tree commit diff
path: root/src/libstore/build.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build.cc')
-rw-r--r--src/libstore/build.cc76
1 files changed, 26 insertions, 50 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index e6ab6310cd49..23cda12c0bfb 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -3,7 +3,6 @@
 #include "misc.hh"
 #include "globals.hh"
 #include "local-store.hh"
-#include "db.hh"
 #include "util.hh"
 
 #include <map>
@@ -207,7 +206,9 @@ private:
     
 public:
 
-    Worker();
+    LocalStore & store;
+
+    Worker(LocalStore & store);
     ~Worker();
 
     /* Make a goal (with caching). */
@@ -897,14 +898,14 @@ void DerivationGoal::haveDerivation()
         return;
     }
 
-    assert(store->isValidPath(drvPath));
+    assert(worker.store.isValidPath(drvPath));
 
     /* Get the derivation. */
     drv = derivationFromPath(drvPath);
 
     for (DerivationOutputs::iterator i = drv.outputs.begin();
          i != drv.outputs.end(); ++i)
-        store->addTempRoot(i->second.path);
+        worker.store.addTempRoot(i->second.path);
 
     /* Check what outputs paths are not already valid. */
     PathSet invalidOutputs = checkPathValidity(false);
@@ -938,7 +939,7 @@ void DerivationGoal::haveDerivation()
          i != invalidOutputs.end(); ++i)
         /* Don't bother creating a substitution goal if there are no
            substitutes. */
-        if (store->hasSubstitutes(*i))
+        if (worker.store.hasSubstitutes(*i))
             addWaitee(worker.makeSubstitutionGoal(*i));
     
     if (waitees.empty()) /* to prevent hang (no wake-up event) */
@@ -993,7 +994,7 @@ void DerivationGoal::outputsSubstituted()
             throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
                 % storePath);
         storePath = toStorePath(storePath);
-        if (!store->isValidPath(storePath))
+        if (!worker.store.isValidPath(storePath))
             throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
                 % storePath);
         
@@ -1250,19 +1251,6 @@ PathSet outputPaths(const DerivationOutputs & outputs)
 }
 
 
-string showPaths(const PathSet & paths)
-{
-    string s;
-    for (PathSet::const_iterator i = paths.begin();
-         i != paths.end(); ++i)
-    {
-        if (s.size() != 0) s += ", ";
-        s += "`" + *i + "'";
-    }
-    return s;
-}
-
-
 DerivationGoal::HookReply DerivationGoal::tryBuildHook()
 {
     if (!useBuildHook) return rpDecline;
@@ -1474,7 +1462,7 @@ DerivationGoal::PrepareBuildReply DerivationGoal::prepareBuild()
          i != drv.outputs.end(); ++i)
     {
         Path path = i->second.path;
-        if (store->isValidPath(path))
+        if (worker.store.isValidPath(path))
             throw BuildError(format("obstructed build: path `%1%' exists") % path);
         if (pathExists(path)) {
             debug(format("removing unregistered path `%1%'") % path);
@@ -1502,7 +1490,7 @@ DerivationGoal::PrepareBuildReply DerivationGoal::prepareBuild()
         /* Add the relevant output closures of the input derivation
            `*i' as input paths.  Only add the closures of output paths
            that are specified as inputs. */
-        assert(store->isValidPath(i->first));
+        assert(worker.store.isValidPath(i->first));
         Derivation inDrv = derivationFromPath(i->first);
         for (StringSet::iterator j = i->second.begin();
              j != i->second.end(); ++j)
@@ -1624,7 +1612,7 @@ void DerivationGoal::startBuilder()
             throw BuildError(format("`exportReferencesGraph' contains a non-store path `%1%'")
                 % storePath);
         storePath = toStorePath(storePath);
-        if (!store->isValidPath(storePath))
+        if (!worker.store.isValidPath(storePath))
             throw BuildError(format("`exportReferencesGraph' contains an invalid path `%1%'")
                 % storePath);
 
@@ -1652,7 +1640,7 @@ void DerivationGoal::startBuilder()
             throw BuildError(format("`exportBuildReferencesGraph' contains a non-store path `%1%'")
                 % storePath);
         storePath = toStorePath(storePath);
-        if (!store->isValidPath(storePath))
+        if (!worker.store.isValidPath(storePath))
             throw BuildError(format("`exportBuildReferencesGraph' contains an invalid path `%1%'")
                 % storePath);
 
@@ -1994,27 +1982,17 @@ void DerivationGoal::computeClosure()
     }
 
     /* Register each output path as valid, and register the sets of
-       paths referenced by each of them.  This is wrapped in one
-       database transaction to ensure that if we crash, either
-       everything is registered or nothing is.  This is for
-       recoverability: unregistered paths in the store can be deleted
-       arbitrarily, while registered paths can only be deleted by
-       running the garbage collector.
-
-       The reason that we do the transaction here and not on the fly
-       while we are scanning (above) is so that we don't hold database
-       locks for too long. */
-    Transaction txn;
-    createStoreTransaction(txn);
+       paths referenced by each of them.  !!! this should be
+       atomic so that either all paths are registered as valid, or
+       none are. */
     for (DerivationOutputs::iterator i = drv.outputs.begin(); 
          i != drv.outputs.end(); ++i)
     {
-        registerValidPath(txn, i->second.path,
+        worker.store.registerValidPath(i->second.path,
             contentHashes[i->second.path],
             allReferences[i->second.path],
             drvPath);
     }
-    txn.commit();
 
     /* It is now safe to delete the lock files, since all future
        lockers will see that the output paths are valid; they will not
@@ -2113,7 +2091,7 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid)
     PathSet result;
     for (DerivationOutputs::iterator i = drv.outputs.begin();
          i != drv.outputs.end(); ++i)
-        if (store->isValidPath(i->second.path)) {
+        if (worker.store.isValidPath(i->second.path)) {
             if (returnValid) result.insert(i->second.path);
         } else {
             if (!returnValid) result.insert(i->second.path);
@@ -2219,10 +2197,10 @@ void SubstitutionGoal::init()
 {
     trace("init");
 
-    store->addTempRoot(storePath);
+    worker.store.addTempRoot(storePath);
     
     /* If the path already exists we're done. */
-    if (store->isValidPath(storePath)) {
+    if (worker.store.isValidPath(storePath)) {
         amDone(ecSuccess);
         return;
     }
@@ -2293,7 +2271,7 @@ void SubstitutionGoal::referencesValid()
     for (PathSet::iterator i = references.begin();
          i != references.end(); ++i)
         if (*i != storePath) /* ignore self-references */
-            assert(store->isValidPath(*i));
+            assert(worker.store.isValidPath(*i));
 
     state = &SubstitutionGoal::tryToRun;
     worker.waitForBuildSlot(shared_from_this());
@@ -2327,7 +2305,7 @@ void SubstitutionGoal::tryToRun()
         (format("waiting for lock on `%1%'") % storePath).str());
 
     /* Check again whether the path is invalid. */
-    if (store->isValidPath(storePath)) {
+    if (worker.store.isValidPath(storePath)) {
         debug(format("store path `%1%' has become valid") % storePath);
         outputLock->setDeletion(true);
         amDone(ecSuccess);
@@ -2434,11 +2412,8 @@ void SubstitutionGoal::finished()
 
     Hash contentHash = hashPath(htSHA256, storePath);
 
-    Transaction txn;
-    createStoreTransaction(txn);
-    registerValidPath(txn, storePath, contentHash,
+    worker.store.registerValidPath(storePath, contentHash,
         references, deriver);
-    txn.commit();
 
     outputLock->setDeletion(true);
     
@@ -2472,7 +2447,8 @@ void SubstitutionGoal::handleEOF(int fd)
 static bool working = false;
 
 
-Worker::Worker()
+Worker::Worker(LocalStore & store)
+    : store(store)
 {
     /* Debugging: prevent recursive workers. */ 
     if (working) abort();
@@ -2870,7 +2846,7 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
     startNest(nest, lvlDebug,
         format("building %1%") % showPaths(drvPaths));
 
-    Worker worker;
+    Worker worker(*this);
 
     Goals goals;
     for (PathSet::const_iterator i = drvPaths.begin();
@@ -2895,9 +2871,9 @@ void LocalStore::buildDerivations(const PathSet & drvPaths)
 void LocalStore::ensurePath(const Path & path)
 {
     /* If the path is already valid, we're done. */
-    if (store->isValidPath(path)) return;
+    if (isValidPath(path)) return;
 
-    Worker worker;
+    Worker worker(*this);
     GoalPtr goal = worker.makeSubstitutionGoal(path);
     Goals goals = singleton<Goals>(goal);