aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build/worker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build/worker.cc')
-rw-r--r--src/libstore/build/worker.cc114
1 files changed, 93 insertions, 21 deletions
diff --git a/src/libstore/build/worker.cc b/src/libstore/build/worker.cc
index b58fc5c1c..f65f63b99 100644
--- a/src/libstore/build/worker.cc
+++ b/src/libstore/build/worker.cc
@@ -2,6 +2,7 @@
#include "worker.hh"
#include "substitution-goal.hh"
#include "drv-output-substitution-goal.hh"
+#include "create-derivation-and-realise-goal.hh"
#include "local-derivation-goal.hh"
#include "hook-instance.hh"
@@ -41,6 +42,24 @@ Worker::~Worker()
}
+std::shared_ptr<CreateDerivationAndRealiseGoal> Worker::makeCreateDerivationAndRealiseGoal(
+ ref<SingleDerivedPath> drvReq,
+ const OutputsSpec & wantedOutputs,
+ BuildMode buildMode)
+{
+ std::weak_ptr<CreateDerivationAndRealiseGoal> & goal_weak = outerDerivationGoals.ensureSlot(*drvReq).value;
+ std::shared_ptr<CreateDerivationAndRealiseGoal> goal = goal_weak.lock();
+ if (!goal) {
+ goal = std::make_shared<CreateDerivationAndRealiseGoal>(drvReq, wantedOutputs, *this, buildMode);
+ goal_weak = goal;
+ wakeUp(goal);
+ } else {
+ goal->addWantedOutputs(wantedOutputs);
+ }
+ return goal;
+}
+
+
std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
const StorePath & drvPath,
const OutputsSpec & wantedOutputs,
@@ -111,10 +130,7 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
{
return std::visit(overloaded {
[&](const DerivedPath::Built & bfd) -> GoalPtr {
- if (auto bop = std::get_if<DerivedPath::Opaque>(&*bfd.drvPath))
- return makeDerivationGoal(bop->path, bfd.outputs, buildMode);
- else
- throw UnimplementedError("Building dynamic derivations in one shot is not yet implemented.");
+ return makeCreateDerivationAndRealiseGoal(bfd.drvPath, bfd.outputs, buildMode);
},
[&](const DerivedPath::Opaque & bo) -> GoalPtr {
return makePathSubstitutionGoal(bo.path, buildMode == bmRepair ? Repair : NoRepair);
@@ -123,24 +139,46 @@ GoalPtr Worker::makeGoal(const DerivedPath & req, BuildMode buildMode)
}
+template<typename K, typename V, typename F>
+static void cullMap(std::map<K, V> & goalMap, F f)
+{
+ for (auto i = goalMap.begin(); i != goalMap.end();)
+ if (!f(i->second))
+ i = goalMap.erase(i);
+ else ++i;
+}
+
+
template<typename K, typename G>
static void removeGoal(std::shared_ptr<G> goal, std::map<K, std::weak_ptr<G>> & goalMap)
{
/* !!! inefficient */
- for (auto i = goalMap.begin();
- i != goalMap.end(); )
- if (i->second.lock() == goal) {
- auto j = i; ++j;
- goalMap.erase(i);
- i = j;
- }
- else ++i;
+ cullMap(goalMap, [&](const std::weak_ptr<G> & gp) -> bool {
+ return gp.lock() != goal;
+ });
+}
+
+template<typename K>
+static void removeGoal(std::shared_ptr<CreateDerivationAndRealiseGoal> goal, std::map<K, DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode> & goalMap);
+
+template<typename K>
+static void removeGoal(std::shared_ptr<CreateDerivationAndRealiseGoal> goal, std::map<K, DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode> & goalMap)
+{
+ /* !!! inefficient */
+ cullMap(goalMap, [&](DerivedPathMap<std::weak_ptr<CreateDerivationAndRealiseGoal>>::ChildNode & node) -> bool {
+ if (node.value.lock() == goal)
+ node.value.reset();
+ removeGoal(goal, node.childMap);
+ return !node.value.expired() || !node.childMap.empty();
+ });
}
void Worker::removeGoal(GoalPtr goal)
{
- if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
+ if (auto drvGoal = std::dynamic_pointer_cast<CreateDerivationAndRealiseGoal>(goal))
+ nix::removeGoal(drvGoal, outerDerivationGoals.map);
+ else if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
nix::removeGoal(drvGoal, derivationGoals);
else if (auto subGoal = std::dynamic_pointer_cast<PathSubstitutionGoal>(goal))
nix::removeGoal(subGoal, substitutionGoals);
@@ -198,8 +236,19 @@ void Worker::childStarted(GoalPtr goal, const std::set<int> & fds,
child.respectTimeouts = respectTimeouts;
children.emplace_back(child);
if (inBuildSlot) {
- if (goal->jobCategory() == JobCategory::Substitution) nrSubstitutions++;
- else nrLocalBuilds++;
+ switch (goal->jobCategory()) {
+ case JobCategory::Substitution:
+ nrSubstitutions++;
+ break;
+ case JobCategory::Build:
+ nrLocalBuilds++;
+ break;
+ case JobCategory::Administration:
+ /* Intentionally not limited, see docs */
+ break;
+ default:
+ abort();
+ }
}
}
@@ -211,12 +260,20 @@ void Worker::childTerminated(Goal * goal, bool wakeSleepers)
if (i == children.end()) return;
if (i->inBuildSlot) {
- if (goal->jobCategory() == JobCategory::Substitution) {
+ switch (goal->jobCategory()) {
+ case JobCategory::Substitution:
assert(nrSubstitutions > 0);
nrSubstitutions--;
- } else {
+ break;
+ case JobCategory::Build:
assert(nrLocalBuilds > 0);
nrLocalBuilds--;
+ break;
+ case JobCategory::Administration:
+ /* Intentionally not limited, see docs */
+ break;
+ default:
+ abort();
}
}
@@ -267,9 +324,9 @@ void Worker::run(const Goals & _topGoals)
for (auto & i : _topGoals) {
topGoals.insert(i);
- if (auto goal = dynamic_cast<DerivationGoal *>(i.get())) {
+ if (auto goal = dynamic_cast<CreateDerivationAndRealiseGoal *>(i.get())) {
topPaths.push_back(DerivedPath::Built {
- .drvPath = makeConstantStorePathRef(goal->drvPath),
+ .drvPath = goal->drvReq,
.outputs = goal->wantedOutputs,
});
} else if (auto goal = dynamic_cast<PathSubstitutionGoal *>(i.get())) {
@@ -522,11 +579,26 @@ void Worker::markContentsGood(const StorePath & path)
}
-GoalPtr upcast_goal(std::shared_ptr<PathSubstitutionGoal> subGoal) {
+GoalPtr upcast_goal(std::shared_ptr<PathSubstitutionGoal> subGoal)
+{
+ return subGoal;
+}
+
+GoalPtr upcast_goal(std::shared_ptr<DrvOutputSubstitutionGoal> subGoal)
+{
return subGoal;
}
-GoalPtr upcast_goal(std::shared_ptr<DrvOutputSubstitutionGoal> subGoal) {
+
+GoalPtr upcast_goal(std::shared_ptr<DerivationGoal> subGoal)
+{
return subGoal;
}
+const DerivationGoal * tryGetConcreteDrvGoal(GoalPtr waitee)
+{
+ auto * odg = dynamic_cast<CreateDerivationAndRealiseGoal *>(&*waitee);
+ if (!odg) return nullptr;
+ return &*odg->concreteDrvGoal;
+}
+
}