libstore: remove Goal::addWaitee

Change-Id: I1b00d1a537d84790878cb0e81aaa1cbaa143d62d
This commit is contained in:
eldritch horrors 2024-08-02 17:00:57 +02:00
parent 4c3010a1be
commit fc987b4123
6 changed files with 43 additions and 34 deletions

View file

@ -174,10 +174,9 @@ Goal::WorkResult DerivationGoal::getDerivation()
return loadDerivation(); return loadDerivation();
} }
addWaitee(worker.makePathSubstitutionGoal(drvPath));
state = &DerivationGoal::loadDerivation; state = &DerivationGoal::loadDerivation;
return StillAlive{}; return WaitForGoals{{worker.makePathSubstitutionGoal(drvPath)}};
} }
@ -268,11 +267,12 @@ Goal::WorkResult DerivationGoal::haveDerivation()
/* We are first going to try to create the invalid output paths /* We are first going to try to create the invalid output paths
through substitutes. If that doesn't work, we'll build through substitutes. If that doesn't work, we'll build
them. */ them. */
WaitForGoals result;
if (settings.useSubstitutes && parsedDrv->substitutesAllowed()) if (settings.useSubstitutes && parsedDrv->substitutesAllowed())
for (auto & [outputName, status] : initialOutputs) { for (auto & [outputName, status] : initialOutputs) {
if (!status.wanted) continue; if (!status.wanted) continue;
if (!status.known) if (!status.known)
addWaitee( result.goals.insert(
worker.makeDrvOutputSubstitutionGoal( worker.makeDrvOutputSubstitutionGoal(
DrvOutput{status.outputHash, outputName}, DrvOutput{status.outputHash, outputName},
buildMode == bmRepair ? Repair : NoRepair buildMode == bmRepair ? Repair : NoRepair
@ -280,18 +280,18 @@ Goal::WorkResult DerivationGoal::haveDerivation()
); );
else { else {
auto * cap = getDerivationCA(*drv); auto * cap = getDerivationCA(*drv);
addWaitee(worker.makePathSubstitutionGoal( result.goals.insert(worker.makePathSubstitutionGoal(
status.known->path, status.known->path,
buildMode == bmRepair ? Repair : NoRepair, buildMode == bmRepair ? Repair : NoRepair,
cap ? std::optional { *cap } : std::nullopt)); cap ? std::optional { *cap } : std::nullopt));
} }
} }
if (waitees.empty()) { /* to prevent hang (no wake-up event) */ if (result.goals.empty()) { /* to prevent hang (no wake-up event) */
return outputsSubstitutionTried(); return outputsSubstitutionTried();
} else { } else {
state = &DerivationGoal::outputsSubstitutionTried; state = &DerivationGoal::outputsSubstitutionTried;
return StillAlive{}; return result;
} }
} }
@ -362,6 +362,8 @@ Goal::WorkResult DerivationGoal::outputsSubstitutionTried()
produced using a substitute. So we have to build instead. */ produced using a substitute. So we have to build instead. */
Goal::WorkResult DerivationGoal::gaveUpOnSubstitution() Goal::WorkResult DerivationGoal::gaveUpOnSubstitution()
{ {
WaitForGoals result;
/* At this point we are building all outputs, so if more are wanted there /* At this point we are building all outputs, so if more are wanted there
is no need to restart. */ is no need to restart. */
needRestart = NeedRestartForMoreOutputs::BuildInProgressWillNotNeed; needRestart = NeedRestartForMoreOutputs::BuildInProgressWillNotNeed;
@ -373,7 +375,7 @@ Goal::WorkResult DerivationGoal::gaveUpOnSubstitution()
addWaiteeDerivedPath = [&](ref<SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) { addWaiteeDerivedPath = [&](ref<SingleDerivedPath> inputDrv, const DerivedPathMap<StringSet>::ChildNode & inputNode) {
if (!inputNode.value.empty()) if (!inputNode.value.empty())
addWaitee(worker.makeGoal( result.goals.insert(worker.makeGoal(
DerivedPath::Built { DerivedPath::Built {
.drvPath = inputDrv, .drvPath = inputDrv,
.outputs = inputNode.value, .outputs = inputNode.value,
@ -418,14 +420,14 @@ Goal::WorkResult DerivationGoal::gaveUpOnSubstitution()
if (!settings.useSubstitutes) if (!settings.useSubstitutes)
throw Error("dependency '%s' of '%s' does not exist, and substitution is disabled", throw Error("dependency '%s' of '%s' does not exist, and substitution is disabled",
worker.store.printStorePath(i), worker.store.printStorePath(drvPath)); worker.store.printStorePath(i), worker.store.printStorePath(drvPath));
addWaitee(worker.makePathSubstitutionGoal(i)); result.goals.insert(worker.makePathSubstitutionGoal(i));
} }
if (waitees.empty()) {/* to prevent hang (no wake-up event) */ if (result.goals.empty()) {/* to prevent hang (no wake-up event) */
return inputsRealised(); return inputsRealised();
} else { } else {
state = &DerivationGoal::inputsRealised; state = &DerivationGoal::inputsRealised;
return StillAlive{}; return result;
} }
} }
@ -466,6 +468,7 @@ Goal::WorkResult DerivationGoal::repairClosure()
} }
/* Check each path (slow!). */ /* Check each path (slow!). */
WaitForGoals result;
for (auto & i : outputClosure) { for (auto & i : outputClosure) {
if (worker.pathContentsGood(i)) continue; if (worker.pathContentsGood(i)) continue;
printError( printError(
@ -473,9 +476,9 @@ Goal::WorkResult DerivationGoal::repairClosure()
worker.store.printStorePath(i), worker.store.printStorePath(drvPath)); worker.store.printStorePath(i), worker.store.printStorePath(drvPath));
auto drvPath2 = outputsToDrv.find(i); auto drvPath2 = outputsToDrv.find(i);
if (drvPath2 == outputsToDrv.end()) if (drvPath2 == outputsToDrv.end())
addWaitee(worker.makePathSubstitutionGoal(i, Repair)); result.goals.insert(worker.makePathSubstitutionGoal(i, Repair));
else else
addWaitee(worker.makeGoal( result.goals.insert(worker.makeGoal(
DerivedPath::Built { DerivedPath::Built {
.drvPath = makeConstantStorePathRef(drvPath2->second), .drvPath = makeConstantStorePathRef(drvPath2->second),
.outputs = OutputsSpec::All { }, .outputs = OutputsSpec::All { },
@ -483,12 +486,12 @@ Goal::WorkResult DerivationGoal::repairClosure()
bmRepair)); bmRepair));
} }
if (waitees.empty()) { if (result.goals.empty()) {
return done(BuildResult::AlreadyValid, assertPathValidity()); return done(BuildResult::AlreadyValid, assertPathValidity());
} }
state = &DerivationGoal::closureRepaired; state = &DerivationGoal::closureRepaired;
return StillAlive{}; return result;
} }
@ -580,10 +583,9 @@ Goal::WorkResult DerivationGoal::inputsRealised()
resolvedDrvGoal = worker.makeDerivationGoal( resolvedDrvGoal = worker.makeDerivationGoal(
pathResolved, wantedOutputs, buildMode); pathResolved, wantedOutputs, buildMode);
addWaitee(resolvedDrvGoal);
state = &DerivationGoal::resolvedFinished; state = &DerivationGoal::resolvedFinished;
return StillAlive{}; return WaitForGoals{{resolvedDrvGoal}};
} }
std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputPaths; std::function<void(const StorePath &, const DerivedPathMap<StringSet>::ChildNode &)> accumInputPaths;

View file

@ -100,6 +100,7 @@ Goal::WorkResult DrvOutputSubstitutionGoal::realisationFetched()
return tryNext(); return tryNext();
} }
WaitForGoals result;
for (const auto & [depId, depPath] : outputInfo->dependentRealisations) { for (const auto & [depId, depPath] : outputInfo->dependentRealisations) {
if (depId != id) { if (depId != id) {
if (auto localOutputInfo = worker.store.queryRealisation(depId); if (auto localOutputInfo = worker.store.queryRealisation(depId);
@ -115,17 +116,17 @@ Goal::WorkResult DrvOutputSubstitutionGoal::realisationFetched()
); );
return tryNext(); return tryNext();
} }
addWaitee(worker.makeDrvOutputSubstitutionGoal(depId)); result.goals.insert(worker.makeDrvOutputSubstitutionGoal(depId));
} }
} }
addWaitee(worker.makePathSubstitutionGoal(outputInfo->outPath)); result.goals.insert(worker.makePathSubstitutionGoal(outputInfo->outPath));
if (waitees.empty()) { if (result.goals.empty()) {
return outPathValid(); return outPathValid();
} else { } else {
state = &DrvOutputSubstitutionGoal::outPathValid; state = &DrvOutputSubstitutionGoal::outPathValid;
return StillAlive{}; return result;
} }
} }

View file

@ -11,13 +11,6 @@ bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) const {
} }
void Goal::addWaitee(GoalPtr waitee)
{
waitees.insert(waitee);
waitee->waiters.insert(shared_from_this());
}
void Goal::trace(std::string_view s) void Goal::trace(std::string_view s)
{ {
debug("%1%: %2%", name, s); debug("%1%: %2%", name, s);

View file

@ -109,13 +109,21 @@ public:
struct [[nodiscard]] WaitForSlot {}; struct [[nodiscard]] WaitForSlot {};
struct [[nodiscard]] WaitForAWhile {}; struct [[nodiscard]] WaitForAWhile {};
struct [[nodiscard]] ContinueImmediately {}; struct [[nodiscard]] ContinueImmediately {};
struct [[nodiscard]] WaitForGoals {
Goals goals;
};
struct [[nodiscard]] Finished { struct [[nodiscard]] Finished {
ExitCode result; ExitCode result;
std::unique_ptr<Error> ex; std::unique_ptr<Error> ex;
}; };
struct [[nodiscard]] WorkResult struct [[nodiscard]] WorkResult : std::variant<
: std::variant<StillAlive, WaitForSlot, WaitForAWhile, ContinueImmediately, Finished> StillAlive,
WaitForSlot,
WaitForAWhile,
ContinueImmediately,
WaitForGoals,
Finished>
{ {
WorkResult() = delete; WorkResult() = delete;
using variant::variant; using variant::variant;
@ -137,8 +145,6 @@ public:
virtual WorkResult work() = 0; virtual WorkResult work() = 0;
void addWaitee(GoalPtr waitee);
virtual void waiteeDone(GoalPtr waitee) { } virtual void waiteeDone(GoalPtr waitee) { }
virtual WorkResult handleChildOutput(int fd, std::string_view data) virtual WorkResult handleChildOutput(int fd, std::string_view data)

View file

@ -152,15 +152,16 @@ Goal::WorkResult PathSubstitutionGoal::tryNext()
/* To maintain the closure invariant, we first have to realise the /* To maintain the closure invariant, we first have to realise the
paths referenced by this one. */ paths referenced by this one. */
WaitForGoals result;
for (auto & i : info->references) for (auto & i : info->references)
if (i != storePath) /* ignore self-references */ if (i != storePath) /* ignore self-references */
addWaitee(worker.makePathSubstitutionGoal(i)); result.goals.insert(worker.makePathSubstitutionGoal(i));
if (waitees.empty()) {/* to prevent hang (no wake-up event) */ if (result.goals.empty()) {/* to prevent hang (no wake-up event) */
return referencesValid(); return referencesValid();
} else { } else {
state = &PathSubstitutionGoal::referencesValid; state = &PathSubstitutionGoal::referencesValid;
return StillAlive{}; return result;
} }
} }

View file

@ -190,6 +190,12 @@ void Worker::handleWorkResult(GoalPtr goal, Goal::WorkResult how)
[&](Goal::WaitForSlot) { waitForBuildSlot(goal); }, [&](Goal::WaitForSlot) { waitForBuildSlot(goal); },
[&](Goal::WaitForAWhile) { waitForAWhile(goal); }, [&](Goal::WaitForAWhile) { waitForAWhile(goal); },
[&](Goal::ContinueImmediately) { wakeUp(goal); }, [&](Goal::ContinueImmediately) { wakeUp(goal); },
[&](Goal::WaitForGoals & w) {
for (auto & dep : w.goals) {
goal->waitees.insert(dep);
dep->waiters.insert(goal);
}
},
[&](Goal::Finished & f) { goalFinished(goal, f); }, [&](Goal::Finished & f) { goalFinished(goal, f); },
}, },
how how