Step cancellation: Don't use pthread_cancel()

This was a bad idea because pthread_cancel() is unsalvageable broken
in C++. Destructors are not allowed to throw exceptions (especially in
C++11), but pthread_cancel() can cause a __cxxabiv1::__forced_unwind
exception inside any destructor that invokes a cancellation
point. (This exception can be caught but *must* be rethrown.) So let's
just kill the builder process instead.
This commit is contained in:
Eelco Dolstra
2016-11-07 19:34:35 +01:00
parent 95aa1f0590
commit 7863d2e1da
4 changed files with 57 additions and 33 deletions

View File

@ -337,20 +337,23 @@ void State::processQueueChange(Connection & conn)
{
auto activeSteps(activeSteps_.lock());
for (auto & activeStep : *activeSteps) {
auto threadId = activeStep->threadId; // FIXME: use Sync or atomic?
if (threadId == 0) continue;
std::set<Build::ptr> dependents;
std::set<Step::ptr> steps;
getDependents(activeStep->step, dependents, steps);
if (!dependents.empty()) continue;
printInfo("cancelling thread for build step %s", activeStep->step->drvPath);
int err = pthread_cancel(threadId);
if (err)
printError("error cancelling thread for build step %s: %s",
activeStep->step->drvPath, strerror(err));
{
auto activeStepState(activeStep->state_.lock());
if (activeStepState->cancelled) continue;
activeStepState->cancelled = true;
if (activeStepState->pid != -1) {
printInfo("killing builder process %d of build step %s",
activeStepState->pid, activeStep->step->drvPath);
if (kill(activeStepState->pid, SIGINT) == -1)
printError("error killing build step %s: %s",
activeStep->step->drvPath, strerror(errno));
}
}
}
}
}