Skip to content

Commit

Permalink
Build derivations in a more predictable order
Browse files Browse the repository at this point in the history
Derivations are now built in order of derivation name, so a package
named "aardvark" is built before "baboon".

Fixes #399.
  • Loading branch information
edolstra committed Nov 24, 2014
1 parent 9e3389c commit b7b6e3d
Showing 1 changed file with 41 additions and 7 deletions.
48 changes: 41 additions & 7 deletions src/libstore/build.cc
Expand Up @@ -84,8 +84,12 @@ class Goal;
typedef std::shared_ptr<Goal> GoalPtr;
typedef std::weak_ptr<Goal> WeakGoalPtr;

struct CompareGoalPtrs {
bool operator() (const GoalPtr & a, const GoalPtr & b);
};

/* Set of goals. */
typedef set<GoalPtr> Goals;
typedef set<GoalPtr, CompareGoalPtrs> Goals;
typedef list<WeakGoalPtr> WeakGoals;

/* A map of paths to goals (and the other way around). */
Expand Down Expand Up @@ -172,11 +176,20 @@ class Goal : public std::enable_shared_from_this<Goal>
(important!), etc. */
virtual void cancel(bool timeout) = 0;

virtual string key() = 0;

protected:
void amDone(ExitCode result);
};


bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) {
string s1 = a->key();
string s2 = b->key();
return s1 < s2;
}


/* A mapping used to remember for each child process to what goal it
belongs, and file descriptors for receiving log data and output
path creation commands. */
Expand Down Expand Up @@ -303,6 +316,7 @@ class Worker
void addToWeakGoals(WeakGoals & goals, GoalPtr p)
{
// FIXME: necessary?
// FIXME: O(n)
foreach (WeakGoals::iterator, i, goals)
if (i->lock() == p) return;
goals.push_back(p);
Expand Down Expand Up @@ -767,6 +781,15 @@ class DerivationGoal : public Goal

void cancel(bool timeout);

string key()
{
/* Ensure that derivations get built in order of their name,
i.e. a derivation named "aardvark" always comes before
"baboon". And substitution goals always happen before
derivation goals (due to "b$"). */
return "b$" + storePathToName(drvPath) + "$" + drvPath;
}

void work();

Path getDrvPath()
Expand Down Expand Up @@ -2575,6 +2598,13 @@ class SubstitutionGoal : public Goal

void cancel(bool timeout);

string key()
{
/* "a$" ensures substitution goals happen before derivation
goals. */
return "a$" + storePathToName(storePath) + "$" + storePath;
}

void work();

/* The states. */
Expand Down Expand Up @@ -3085,15 +3115,19 @@ void Worker::run(const Goals & _topGoals)

checkInterrupt();

/* Call every wake goal. */
/* Call every wake goal (in the ordering established by
CompareGoalPtrs). */
while (!awake.empty() && !topGoals.empty()) {
WeakGoals awake2(awake);
Goals awake2;
for (auto & i : awake) {
GoalPtr goal = i.lock();
if (goal) awake2.insert(goal);
}
awake.clear();
foreach (WeakGoals::iterator, i, awake2) {
for (auto & goal : awake2) {
checkInterrupt();
GoalPtr goal = i->lock();
if (goal) goal->work();
if (topGoals.empty()) break;
goal->work();
if (topGoals.empty()) break; // stuff may have been cancelled
}
}

Expand Down

0 comments on commit b7b6e3d

Please sign in to comment.