forked from lix-project/lix
Fix --fallback
This fixes an assertion failure in "assert(goal);" in Worker::waitForInput() after a substitution goal is cancelled by the termination of another goal. The problem was the line //worker.childTerminated(shared_from_this()); // FIXME in the SubstitutionGoal destructor. This was disabled because shared_from_this() obviously doesn't work from a destructor. So we now use a real pointer for object identity.
This commit is contained in:
parent
dd85fc1c5a
commit
97b1af1cbe
|
@ -193,6 +193,7 @@ bool CompareGoalPtrs::operator() (const GoalPtr & a, const GoalPtr & b) {
|
||||||
struct Child
|
struct Child
|
||||||
{
|
{
|
||||||
WeakGoalPtr goal;
|
WeakGoalPtr goal;
|
||||||
|
Goal * goal2; // ugly hackery
|
||||||
set<int> fds;
|
set<int> fds;
|
||||||
bool respectTimeouts;
|
bool respectTimeouts;
|
||||||
bool inBuildSlot;
|
bool inBuildSlot;
|
||||||
|
@ -284,7 +285,7 @@ public:
|
||||||
false if there is no sense in waking up goals that are sleeping
|
false if there is no sense in waking up goals that are sleeping
|
||||||
because they can't run yet (e.g., there is no free build slot,
|
because they can't run yet (e.g., there is no free build slot,
|
||||||
or the hook would still say `postpone'). */
|
or the hook would still say `postpone'). */
|
||||||
void childTerminated(GoalPtr goal, bool wakeSleepers = true);
|
void childTerminated(Goal * goal, bool wakeSleepers = true);
|
||||||
|
|
||||||
/* Put `goal' to sleep until a build slot becomes available (which
|
/* Put `goal' to sleep until a build slot becomes available (which
|
||||||
might be right away). */
|
might be right away). */
|
||||||
|
@ -935,7 +936,7 @@ DerivationGoal::~DerivationGoal()
|
||||||
void DerivationGoal::killChild()
|
void DerivationGoal::killChild()
|
||||||
{
|
{
|
||||||
if (pid != -1) {
|
if (pid != -1) {
|
||||||
worker.childTerminated(shared_from_this());
|
worker.childTerminated(this);
|
||||||
|
|
||||||
if (buildUser.enabled()) {
|
if (buildUser.enabled()) {
|
||||||
/* If we're using a build user, then there is a tricky
|
/* If we're using a build user, then there is a tricky
|
||||||
|
@ -1409,7 +1410,7 @@ void DerivationGoal::buildDone()
|
||||||
debug(format("builder process for ‘%1%’ finished") % drvPath);
|
debug(format("builder process for ‘%1%’ finished") % drvPath);
|
||||||
|
|
||||||
/* So the child is gone now. */
|
/* So the child is gone now. */
|
||||||
worker.childTerminated(shared_from_this());
|
worker.childTerminated(this);
|
||||||
|
|
||||||
/* Close the read side of the logger pipe. */
|
/* Close the read side of the logger pipe. */
|
||||||
if (hook) {
|
if (hook) {
|
||||||
|
@ -3141,8 +3142,9 @@ SubstitutionGoal::~SubstitutionGoal()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if (thr.joinable()) {
|
if (thr.joinable()) {
|
||||||
|
// FIXME: signal worker thread to quit.
|
||||||
thr.join();
|
thr.join();
|
||||||
//worker.childTerminated(shared_from_this()); // FIXME
|
worker.childTerminated(this);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
|
@ -3297,7 +3299,7 @@ void SubstitutionGoal::finished()
|
||||||
trace("substitute finished");
|
trace("substitute finished");
|
||||||
|
|
||||||
thr.join();
|
thr.join();
|
||||||
worker.childTerminated(shared_from_this());
|
worker.childTerminated(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
promise.get_future().get();
|
promise.get_future().get();
|
||||||
|
@ -3450,6 +3452,7 @@ void Worker::childStarted(GoalPtr goal, const set<int> & fds,
|
||||||
{
|
{
|
||||||
Child child;
|
Child child;
|
||||||
child.goal = goal;
|
child.goal = goal;
|
||||||
|
child.goal2 = goal.get();
|
||||||
child.fds = fds;
|
child.fds = fds;
|
||||||
child.timeStarted = child.lastOutput = time(0);
|
child.timeStarted = child.lastOutput = time(0);
|
||||||
child.inBuildSlot = inBuildSlot;
|
child.inBuildSlot = inBuildSlot;
|
||||||
|
@ -3459,10 +3462,10 @@ void Worker::childStarted(GoalPtr goal, const set<int> & fds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Worker::childTerminated(GoalPtr goal, bool wakeSleepers)
|
void Worker::childTerminated(Goal * goal, bool wakeSleepers)
|
||||||
{
|
{
|
||||||
auto i = std::find_if(children.begin(), children.end(),
|
auto i = std::find_if(children.begin(), children.end(),
|
||||||
[&](const Child & child) { return child.goal.lock() == goal; });
|
[&](const Child & child) { return child.goal2 == goal; });
|
||||||
assert(i != children.end());
|
assert(i != children.end());
|
||||||
|
|
||||||
if (i->inBuildSlot) {
|
if (i->inBuildSlot) {
|
||||||
|
|
Loading…
Reference in a new issue