* Don't go into a (sometimes infinite) loop calling the build hook.
This commit is contained in:
parent
638ce339a5
commit
056cd1d3b7
1 changed files with 24 additions and 16 deletions
|
@ -164,10 +164,10 @@ public:
|
||||||
/* Registers / unregisters a running child process. */
|
/* Registers / unregisters a running child process. */
|
||||||
void childStarted(GoalPtr goal, pid_t pid, int fdOutput,
|
void childStarted(GoalPtr goal, pid_t pid, int fdOutput,
|
||||||
bool inBuildSlot);
|
bool inBuildSlot);
|
||||||
void childTerminated(pid_t pid);
|
void childTerminated(pid_t pid, bool wakeSleepers = true);
|
||||||
|
|
||||||
/* Add a goal to the set of goals waiting for a build slot. */
|
/* Add a goal to the set of goals waiting for a build slot. */
|
||||||
void waitForBuildSlot(GoalPtr goal);
|
void waitForBuildSlot(GoalPtr goal, bool reallyWait = false);
|
||||||
|
|
||||||
/* Loop until the specified top-level goal has finished. Returns
|
/* Loop until the specified top-level goal has finished. Returns
|
||||||
true if it has finished succesfully. */
|
true if it has finished succesfully. */
|
||||||
|
@ -553,7 +553,7 @@ void NormalisationGoal::tryToBuild()
|
||||||
return;
|
return;
|
||||||
case rpPostpone:
|
case rpPostpone:
|
||||||
/* Not now; wait until at least one child finishes. */
|
/* Not now; wait until at least one child finishes. */
|
||||||
worker.waitForBuildSlot(shared_from_this());
|
worker.waitForBuildSlot(shared_from_this(), true);
|
||||||
return;
|
return;
|
||||||
case rpDecline:
|
case rpDecline:
|
||||||
/* We should do it ourselves. */
|
/* We should do it ourselves. */
|
||||||
|
@ -813,7 +813,7 @@ void NormalisationGoal::terminateBuildHook()
|
||||||
debug("terminating build hook");
|
debug("terminating build hook");
|
||||||
pid_t savedPid = pid;
|
pid_t savedPid = pid;
|
||||||
pid.wait(true);
|
pid.wait(true);
|
||||||
worker.childTerminated(savedPid);
|
worker.childTerminated(savedPid, false);
|
||||||
fromHook.readSide.close();
|
fromHook.readSide.close();
|
||||||
toHook.writeSide.close();
|
toHook.writeSide.close();
|
||||||
fdLogFile.close();
|
fdLogFile.close();
|
||||||
|
@ -1821,7 +1821,7 @@ void Worker::childStarted(GoalPtr goal,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::childTerminated(pid_t pid)
|
void Worker::childTerminated(pid_t pid, bool wakeSleepers)
|
||||||
{
|
{
|
||||||
Children::iterator i = children.find(pid);
|
Children::iterator i = children.find(pid);
|
||||||
assert(i != children.end());
|
assert(i != children.end());
|
||||||
|
@ -1833,21 +1833,29 @@ void Worker::childTerminated(pid_t pid)
|
||||||
|
|
||||||
children.erase(pid);
|
children.erase(pid);
|
||||||
|
|
||||||
/* Wake up goals waiting for a build slot. */
|
if (wakeSleepers) {
|
||||||
for (WeakGoals::iterator i = wantingToBuild.begin();
|
|
||||||
i != wantingToBuild.end(); ++i)
|
/* Wake up goals waiting for a build slot. */
|
||||||
{
|
for (WeakGoals::iterator i = wantingToBuild.begin();
|
||||||
GoalPtr goal = i->lock();
|
i != wantingToBuild.end(); ++i)
|
||||||
if (goal) wakeUp(goal);
|
{
|
||||||
|
GoalPtr goal = i->lock();
|
||||||
|
if (goal) wakeUp(goal);
|
||||||
|
}
|
||||||
|
|
||||||
|
wantingToBuild.clear();
|
||||||
|
|
||||||
}
|
}
|
||||||
wantingToBuild.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::waitForBuildSlot(GoalPtr goal)
|
void Worker::waitForBuildSlot(GoalPtr goal, bool reallyWait)
|
||||||
{
|
{
|
||||||
debug("wait for build slot");
|
debug("wait for build slot");
|
||||||
if (canBuildMore())
|
if (reallyWait && children.size() == 0)
|
||||||
|
throw Error("waiting for a build slot, yet there are no children - "
|
||||||
|
"maybe the build hook gave an inappropriate `postpone' reply?");
|
||||||
|
if (!reallyWait && canBuildMore())
|
||||||
wakeUp(goal); /* we can do it right away */
|
wakeUp(goal); /* we can do it right away */
|
||||||
else
|
else
|
||||||
wantingToBuild.insert(goal);
|
wantingToBuild.insert(goal);
|
||||||
|
@ -1981,7 +1989,7 @@ Path realiseStoreExpr(const Path & nePath)
|
||||||
|
|
||||||
Worker worker;
|
Worker worker;
|
||||||
if (!worker.run(worker.makeRealisationGoal(nePath)))
|
if (!worker.run(worker.makeRealisationGoal(nePath)))
|
||||||
throw Error(format("realisation of store expressions `%1%' failed") % nePath);
|
throw Error(format("realisation of store expression `%1%' failed") % nePath);
|
||||||
|
|
||||||
return queryNormalForm(nePath);
|
return queryNormalForm(nePath);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue