nix-super/src/libstore/build/goal.cc

90 lines
2.1 KiB
C++
Raw Normal View History

#include "goal.hh"
#include "worker.hh"
namespace nix {
2017-12-11 20:05:14 +02:00
bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) const {
string s1 = a->key();
string s2 = b->key();
return s1 < s2;
}
2014-03-30 01:49:23 +02:00
void addToWeakGoals(WeakGoals & goals, GoalPtr p)
{
// FIXME: necessary?
// FIXME: O(n)
2015-07-17 20:24:28 +03:00
for (auto & i : goals)
if (i.lock() == p) return;
2014-03-30 01:49:23 +02:00
goals.push_back(p);
}
void Goal::addWaitee(GoalPtr waitee)
{
waitees.insert(waitee);
2014-03-30 01:49:23 +02:00
addToWeakGoals(waitee->waiters, shared_from_this());
}
void Goal::waiteeDone(GoalPtr waitee, ExitCode result)
{
assert(waitees.find(waitee) != waitees.end());
waitees.erase(waitee);
trace(fmt("waitee '%s' done; %d left", waitee->name, waitees.size()));
2012-07-27 16:59:18 +03:00
if (result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure) ++nrFailed;
if (result == ecNoSubstituters) ++nrNoSubstituters;
2012-07-27 16:59:18 +03:00
if (result == ecIncompleteClosure) ++nrIncompleteClosure;
if (waitees.empty() || (result == ecFailed && !settings.keepGoing)) {
/* If we failed and keepGoing is not set, we remove all
remaining waitees. */
2015-07-17 20:24:28 +03:00
for (auto & goal : waitees) {
WeakGoals waiters2;
2015-07-17 20:24:28 +03:00
for (auto & j : goal->waiters)
if (j.lock() != shared_from_this()) waiters2.push_back(j);
goal->waiters = waiters2;
}
waitees.clear();
worker.wakeUp(shared_from_this());
}
}
void Goal::amDone(ExitCode result, std::optional<Error> ex)
{
trace("done");
assert(exitCode == ecBusy);
assert(result == ecSuccess || result == ecFailed || result == ecNoSubstituters || result == ecIncompleteClosure);
exitCode = result;
if (ex) {
if (!waiters.empty())
logError(ex->info());
else
this->ex = std::move(*ex);
}
2015-07-17 20:24:28 +03:00
for (auto & i : waiters) {
GoalPtr goal = i.lock();
if (goal) goal->waiteeDone(shared_from_this(), result);
}
waiters.clear();
worker.removeGoal(shared_from_this());
}
void Goal::trace(const FormatOrString & fs)
{
debug("%1%: %2%", name, fs.s);
}
}