Remove abstractions around job list

Directly access the job list without the intermediate job_iterator_t,
and remove functions that are ripe for abuse by modifying a local
enumeration of the same list instead of operating on the iterators
directly (e.g. proc.cpp iterates jobs, and mid-iteration calls
parser::job_remove(j) with the job (and not the iterator to the job),
causing an invisible invalidation of the pre-existing local iterators.
This commit is contained in:
Mahmoud Al-Qudsi
2018-12-30 21:25:16 -06:00
parent 0c5015d467
commit f8e0e0ef82
11 changed files with 87 additions and 150 deletions

View File

@@ -784,10 +784,8 @@ parse_execution_result_t parse_execution_context_t::populate_plain_process(
// Protect against exec with background processes running
static uint32_t last_exec_run_counter = -1;
if (process_type == process_type_t::exec && shell_is_interactive()) {
job_iterator_t jobs;
bool have_bg = false;
const job_t *bg = nullptr;
while ((bg = jobs.next())) {
for (const auto bg : jobs()) {
// The assumption here is that if it is a foreground job,
// it's related to us.
// This stops us from asking if we're doing `exec` inside a function.
@@ -1130,6 +1128,16 @@ parse_execution_result_t parse_execution_context_t::populate_job_from_job_node(
return result;
}
static bool remove_job(job_t *job) {
for (auto j = jobs().begin(); j != jobs().end(); ++j) {
if (j->get() == job) {
jobs().erase(j);
return true;
}
}
return false;
}
parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> job_node,
const block_t *associated_block) {
if (should_cancel_execution(associated_block)) {
@@ -1253,7 +1261,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> jo
// Actually execute the job.
if (!exec_job(*this->parser, job)) {
parser->job_remove(job.get());
remove_job(job.get());
}
// Only external commands require a new fishd barrier.