forked from lix-project/lix
Fix tests on systems with a non-master git defaultBranch #1
4 changed files with 45 additions and 21 deletions
|
@ -130,8 +130,12 @@ kj::Promise<Result<Goal::WorkResult>> DerivationGoal::work() noexcept
|
||||||
return useDerivation ? getDerivation() : haveDerivation();
|
return useDerivation ? getDerivation() : haveDerivation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
bool DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
||||||
{
|
{
|
||||||
|
if (isDone) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto newWanted = wantedOutputs.union_(outputs);
|
auto newWanted = wantedOutputs.union_(outputs);
|
||||||
switch (needRestart) {
|
switch (needRestart) {
|
||||||
case NeedRestartForMoreOutputs::OutputsUnmodifedDontNeed:
|
case NeedRestartForMoreOutputs::OutputsUnmodifedDontNeed:
|
||||||
|
@ -148,6 +152,7 @@ void DerivationGoal::addWantedOutputs(const OutputsSpec & outputs)
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
wantedOutputs = newWanted;
|
wantedOutputs = newWanted;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1680,6 +1685,8 @@ Goal::Finished DerivationGoal::done(
|
||||||
SingleDrvOutputs builtOutputs,
|
SingleDrvOutputs builtOutputs,
|
||||||
std::optional<Error> ex)
|
std::optional<Error> ex)
|
||||||
{
|
{
|
||||||
|
isDone = true;
|
||||||
|
|
||||||
outputLocks.unlock();
|
outputLocks.unlock();
|
||||||
buildResult.status = status;
|
buildResult.status = status;
|
||||||
if (ex)
|
if (ex)
|
||||||
|
|
|
@ -73,6 +73,12 @@ struct DerivationGoal : public Goal
|
||||||
{
|
{
|
||||||
struct InputStream;
|
struct InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this goal has completed. Completed goals can not be
|
||||||
|
* asked for more outputs, a new goal must be created instead.
|
||||||
|
*/
|
||||||
|
bool isDone = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to use an on-disk .drv file.
|
* Whether to use an on-disk .drv file.
|
||||||
*/
|
*/
|
||||||
|
@ -249,7 +255,7 @@ struct DerivationGoal : public Goal
|
||||||
/**
|
/**
|
||||||
* Add wanted outputs to an already existing derivation goal.
|
* Add wanted outputs to an already existing derivation goal.
|
||||||
*/
|
*/
|
||||||
void addWantedOutputs(const OutputsSpec & outputs);
|
bool addWantedOutputs(const OutputsSpec & outputs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The states.
|
* The states.
|
||||||
|
|
|
@ -57,25 +57,36 @@ std::pair<std::shared_ptr<G>, kj::Promise<void>> Worker::makeGoalCommon(
|
||||||
std::map<ID, CachedGoal<G>> & map,
|
std::map<ID, CachedGoal<G>> & map,
|
||||||
const ID & key,
|
const ID & key,
|
||||||
InvocableR<std::unique_ptr<G>> auto create,
|
InvocableR<std::unique_ptr<G>> auto create,
|
||||||
std::invocable<G &> auto modify
|
InvocableR<bool, G &> auto modify
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
auto [it, _inserted] = map.try_emplace(key);
|
auto [it, _inserted] = map.try_emplace(key);
|
||||||
|
// try twice to create the goal. we can only loop if we hit the continue,
|
||||||
|
// and then we only want to recreate the goal *once*. concurrent accesses
|
||||||
|
// to the worker are not sound, we want to catch them if at all possible.
|
||||||
|
for ([[maybe_unused]] auto _attempt : {1, 2}) {
|
||||||
auto & goal_weak = it->second;
|
auto & goal_weak = it->second;
|
||||||
auto goal = goal_weak.goal.lock();
|
auto goal = goal_weak.goal.lock();
|
||||||
if (!goal) {
|
if (!goal) {
|
||||||
goal = create();
|
goal = create();
|
||||||
goal->notify = std::move(goal_weak.fulfiller);
|
goal->notify = std::move(goal_weak.fulfiller);
|
||||||
goal_weak.goal = goal;
|
goal_weak.goal = goal;
|
||||||
// do not start working immediately, this round of the event loop
|
// do not start working immediately. if we are not yet running we
|
||||||
// may have more calls to this function lined up that'll also run
|
// may create dependencies as though they were toplevel goals, in
|
||||||
// modify(). starting early can then cause the goals to misbehave
|
// which case the dependencies will not report build errors. when
|
||||||
|
// we are running we may be called for this same goal more times,
|
||||||
|
// and then we want to modify rather than recreate when possible.
|
||||||
childStarted(goal, kj::evalLater([goal] { return goal->work(); }));
|
childStarted(goal, kj::evalLater([goal] { return goal->work(); }));
|
||||||
} else {
|
} else {
|
||||||
modify(*goal);
|
if (!modify(*goal)) {
|
||||||
|
goal_weak = {};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return {goal, goal_weak.promise->addBranch()};
|
return {goal, goal_weak.promise->addBranch()};
|
||||||
}
|
}
|
||||||
|
assert(false && "could not make a goal. possible concurrent worker access");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeDerivationGoal(
|
||||||
|
@ -94,7 +105,7 @@ std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeDeriva
|
||||||
drvPath, wantedOutputs, *this, running, buildMode
|
drvPath, wantedOutputs, *this, running, buildMode
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[&](DerivationGoal & g) { g.addWantedOutputs(wantedOutputs); }
|
[&](DerivationGoal & g) { return g.addWantedOutputs(wantedOutputs); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +129,7 @@ std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> Worker::makeBasicD
|
||||||
drvPath, drv, wantedOutputs, *this, running, buildMode
|
drvPath, drv, wantedOutputs, *this, running, buildMode
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[&](DerivationGoal & g) { g.addWantedOutputs(wantedOutputs); }
|
[&](DerivationGoal & g) { return g.addWantedOutputs(wantedOutputs); }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +143,7 @@ Worker::makePathSubstitutionGoal(
|
||||||
substitutionGoals,
|
substitutionGoals,
|
||||||
path,
|
path,
|
||||||
[&] { return std::make_unique<PathSubstitutionGoal>(path, *this, running, repair, ca); },
|
[&] { return std::make_unique<PathSubstitutionGoal>(path, *this, running, repair, ca); },
|
||||||
[&](auto &) {}
|
[&](auto &) { return true; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,7 +157,7 @@ Worker::makeDrvOutputSubstitutionGoal(
|
||||||
drvOutputSubstitutionGoals,
|
drvOutputSubstitutionGoals,
|
||||||
id,
|
id,
|
||||||
[&] { return std::make_unique<DrvOutputSubstitutionGoal>(id, *this, running, repair, ca); },
|
[&] { return std::make_unique<DrvOutputSubstitutionGoal>(id, *this, running, repair, ca); },
|
||||||
[&](auto &) {}
|
[&](auto &) { return true; }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ private:
|
||||||
std::map<ID, CachedGoal<G>> & map,
|
std::map<ID, CachedGoal<G>> & map,
|
||||||
const ID & key,
|
const ID & key,
|
||||||
InvocableR<std::unique_ptr<G>> auto create,
|
InvocableR<std::unique_ptr<G>> auto create,
|
||||||
std::invocable<G &> auto modify
|
InvocableR<bool, G &> auto modify
|
||||||
);
|
);
|
||||||
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeDerivationGoal(
|
std::pair<std::shared_ptr<DerivationGoal>, kj::Promise<void>> makeDerivationGoal(
|
||||||
const StorePath & drvPath,
|
const StorePath & drvPath,
|
||||||
|
|
Loading…
Reference in a new issue