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