Merge pull request #4143 from obsidiansystems/typed-goal-maps
Properly type the derivation and substitution goal maps
This commit is contained in:
commit
fda835b231
|
@ -231,7 +231,7 @@ void DerivationGoal::getDerivation()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
addWaitee(worker.makeSubstitutionGoal(drvPath));
|
addWaitee(upcast_goal(worker.makeSubstitutionGoal(drvPath)));
|
||||||
|
|
||||||
state = &DerivationGoal::loadDerivation;
|
state = &DerivationGoal::loadDerivation;
|
||||||
}
|
}
|
||||||
|
@ -304,10 +304,10 @@ void DerivationGoal::haveDerivation()
|
||||||
/* Nothing to wait for; tail call */
|
/* Nothing to wait for; tail call */
|
||||||
return DerivationGoal::gaveUpOnSubstitution();
|
return DerivationGoal::gaveUpOnSubstitution();
|
||||||
}
|
}
|
||||||
addWaitee(worker.makeSubstitutionGoal(
|
addWaitee(upcast_goal(worker.makeSubstitutionGoal(
|
||||||
status.known->path,
|
status.known->path,
|
||||||
buildMode == bmRepair ? Repair : NoRepair,
|
buildMode == bmRepair ? Repair : NoRepair,
|
||||||
getDerivationCA(*drv)));
|
getDerivationCA(*drv))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||||
|
@ -388,7 +388,7 @@ void 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.makeSubstitutionGoal(i));
|
addWaitee(upcast_goal(worker.makeSubstitutionGoal(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
if (waitees.empty()) /* to prevent hang (no wake-up event) */
|
||||||
|
@ -442,7 +442,7 @@ void DerivationGoal::repairClosure()
|
||||||
});
|
});
|
||||||
auto drvPath2 = outputsToDrv.find(i);
|
auto drvPath2 = outputsToDrv.find(i);
|
||||||
if (drvPath2 == outputsToDrv.end())
|
if (drvPath2 == outputsToDrv.end())
|
||||||
addWaitee(worker.makeSubstitutionGoal(i, Repair));
|
addWaitee(upcast_goal(worker.makeSubstitutionGoal(i, Repair)));
|
||||||
else
|
else
|
||||||
addWaitee(worker.makeDerivationGoal(drvPath2->second, StringSet(), bmRepair));
|
addWaitee(worker.makeDerivationGoal(drvPath2->second, StringSet(), bmRepair));
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,16 +43,13 @@ std::shared_ptr<DerivationGoal> Worker::makeDerivationGoalCommon(
|
||||||
const StringSet & wantedOutputs,
|
const StringSet & wantedOutputs,
|
||||||
std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal)
|
std::function<std::shared_ptr<DerivationGoal>()> mkDrvGoal)
|
||||||
{
|
{
|
||||||
WeakGoalPtr & abstract_goal_weak = derivationGoals[drvPath];
|
std::weak_ptr<DerivationGoal> & goal_weak = derivationGoals[drvPath];
|
||||||
GoalPtr abstract_goal = abstract_goal_weak.lock(); // FIXME
|
std::shared_ptr<DerivationGoal> goal = goal_weak.lock();
|
||||||
std::shared_ptr<DerivationGoal> goal;
|
if (!goal) {
|
||||||
if (!abstract_goal) {
|
|
||||||
goal = mkDrvGoal();
|
goal = mkDrvGoal();
|
||||||
abstract_goal_weak = goal;
|
goal_weak = goal;
|
||||||
wakeUp(goal);
|
wakeUp(goal);
|
||||||
} else {
|
} else {
|
||||||
goal = std::dynamic_pointer_cast<DerivationGoal>(abstract_goal);
|
|
||||||
assert(goal);
|
|
||||||
goal->addWantedOutputs(wantedOutputs);
|
goal->addWantedOutputs(wantedOutputs);
|
||||||
}
|
}
|
||||||
return goal;
|
return goal;
|
||||||
|
@ -77,10 +74,10 @@ std::shared_ptr<DerivationGoal> Worker::makeBasicDerivationGoal(const StorePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca)
|
std::shared_ptr<SubstitutionGoal> Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair, std::optional<ContentAddress> ca)
|
||||||
{
|
{
|
||||||
WeakGoalPtr & goal_weak = substitutionGoals[path];
|
std::weak_ptr<SubstitutionGoal> & goal_weak = substitutionGoals[path];
|
||||||
GoalPtr goal = goal_weak.lock(); // FIXME
|
auto goal = goal_weak.lock(); // FIXME
|
||||||
if (!goal) {
|
if (!goal) {
|
||||||
goal = std::make_shared<SubstitutionGoal>(path, *this, repair, ca);
|
goal = std::make_shared<SubstitutionGoal>(path, *this, repair, ca);
|
||||||
goal_weak = goal;
|
goal_weak = goal;
|
||||||
|
@ -89,14 +86,14 @@ GoalPtr Worker::makeSubstitutionGoal(const StorePath & path, RepairFlag repair,
|
||||||
return goal;
|
return goal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename G>
|
||||||
static void removeGoal(GoalPtr goal, WeakGoalMap & goalMap)
|
static void removeGoal(std::shared_ptr<G> goal, std::map<StorePath, std::weak_ptr<G>> & goalMap)
|
||||||
{
|
{
|
||||||
/* !!! inefficient */
|
/* !!! inefficient */
|
||||||
for (WeakGoalMap::iterator i = goalMap.begin();
|
for (auto i = goalMap.begin();
|
||||||
i != goalMap.end(); )
|
i != goalMap.end(); )
|
||||||
if (i->second.lock() == goal) {
|
if (i->second.lock() == goal) {
|
||||||
WeakGoalMap::iterator j = i; ++j;
|
auto j = i; ++j;
|
||||||
goalMap.erase(i);
|
goalMap.erase(i);
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
|
@ -106,8 +103,12 @@ static void removeGoal(GoalPtr goal, WeakGoalMap & goalMap)
|
||||||
|
|
||||||
void Worker::removeGoal(GoalPtr goal)
|
void Worker::removeGoal(GoalPtr goal)
|
||||||
{
|
{
|
||||||
nix::removeGoal(goal, derivationGoals);
|
if (auto drvGoal = std::dynamic_pointer_cast<DerivationGoal>(goal))
|
||||||
nix::removeGoal(goal, substitutionGoals);
|
nix::removeGoal(drvGoal, derivationGoals);
|
||||||
|
else if (auto subGoal = std::dynamic_pointer_cast<SubstitutionGoal>(goal))
|
||||||
|
nix::removeGoal(subGoal, substitutionGoals);
|
||||||
|
else
|
||||||
|
assert(false);
|
||||||
if (topGoals.find(goal) != topGoals.end()) {
|
if (topGoals.find(goal) != topGoals.end()) {
|
||||||
topGoals.erase(goal);
|
topGoals.erase(goal);
|
||||||
/* If a top-level goal failed, then kill all other goals
|
/* If a top-level goal failed, then kill all other goals
|
||||||
|
@ -452,4 +453,9 @@ void Worker::markContentsGood(const StorePath & path)
|
||||||
pathContentsGoodCache.insert_or_assign(path, true);
|
pathContentsGoodCache.insert_or_assign(path, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GoalPtr upcast_goal(std::shared_ptr<SubstitutionGoal> subGoal) {
|
||||||
|
return subGoal;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,18 @@ namespace nix {
|
||||||
|
|
||||||
/* Forward definition. */
|
/* Forward definition. */
|
||||||
class DerivationGoal;
|
class DerivationGoal;
|
||||||
|
class SubstitutionGoal;
|
||||||
|
|
||||||
|
/* Workaround for not being able to declare a something like
|
||||||
|
|
||||||
|
class SubstitutionGoal : public Goal;
|
||||||
|
|
||||||
|
even when Goal is a complete type.
|
||||||
|
|
||||||
|
This is still a static cast. The purpose of exporting it is to define it in
|
||||||
|
a place where `SubstitutionGoal` is concrete, and use it in a place where it
|
||||||
|
is opaque. */
|
||||||
|
GoalPtr upcast_goal(std::shared_ptr<SubstitutionGoal> subGoal);
|
||||||
|
|
||||||
typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
|
typedef std::chrono::time_point<std::chrono::steady_clock> steady_time_point;
|
||||||
|
|
||||||
|
@ -56,8 +68,8 @@ private:
|
||||||
|
|
||||||
/* Maps used to prevent multiple instantiations of a goal for the
|
/* Maps used to prevent multiple instantiations of a goal for the
|
||||||
same derivation / path. */
|
same derivation / path. */
|
||||||
WeakGoalMap derivationGoals;
|
std::map<StorePath, std::weak_ptr<DerivationGoal>> derivationGoals;
|
||||||
WeakGoalMap substitutionGoals;
|
std::map<StorePath, std::weak_ptr<SubstitutionGoal>> substitutionGoals;
|
||||||
|
|
||||||
/* Goals waiting for busy paths to be unlocked. */
|
/* Goals waiting for busy paths to be unlocked. */
|
||||||
WeakGoals waitingForAnyGoal;
|
WeakGoals waitingForAnyGoal;
|
||||||
|
@ -131,7 +143,7 @@ public:
|
||||||
const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
|
const StringSet & wantedOutputs, BuildMode buildMode = bmNormal);
|
||||||
|
|
||||||
/* substitution goal */
|
/* substitution goal */
|
||||||
GoalPtr makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt);
|
std::shared_ptr<SubstitutionGoal> makeSubstitutionGoal(const StorePath & storePath, RepairFlag repair = NoRepair, std::optional<ContentAddress> ca = std::nullopt);
|
||||||
|
|
||||||
/* Remove a dead goal. */
|
/* Remove a dead goal. */
|
||||||
void removeGoal(GoalPtr goal);
|
void removeGoal(GoalPtr goal);
|
||||||
|
|
Loading…
Reference in a new issue