Eliminate the job from block_t

This exists only to support the '--on-job-exit caller' feature.
Just store the calling job ID directly in the parser's libdata.
This commit is contained in:
ridiculousfish 2019-05-12 14:42:18 -07:00
parent 6e0cf5db6f
commit 5158ee812b
4 changed files with 15 additions and 25 deletions

View file

@ -93,19 +93,7 @@ static int parse_cmd_opts(function_cmd_opts_t &opts, int *optind, //!OCLINT(hig
job_id_t job_id = -1;
if (is_subshell) {
size_t block_idx = 0;
// Find the outermost substitution block.
for (block_idx = 0;; block_idx++) {
const block_t *b = parser.block_at_index(block_idx);
if (b == NULL || b->type() == SUBST) break;
}
// Go one step beyond that, to get to the caller.
const block_t *caller_block = parser.block_at_index(block_idx + 1);
if (caller_block != NULL && caller_block->job != NULL) {
job_id = caller_block->job->job_id;
}
job_id = parser.libdata().caller_job_id;
}
if (job_id == -1) {

View file

@ -1240,27 +1240,28 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> jo
job->set_flag(job_flag_t::SKIP_NOTIFICATION,
is_subshell || is_block || is_event || !shell_is_interactive());
// Tell the current block what its job is. This has to happen before we populate it (#1394).
parser->current_block()->job = job;
// We are about to populate a job. One possible argument to the job is a command substitution
// which may be interested in the job that's populating it, via '--on-job-exit caller'. Record
// the job ID here.
auto &libdata = parser->libdata();
const auto saved_caller_jid = libdata.caller_job_id;
libdata.caller_job_id = job->job_id;
// Populate the job. This may fail for reasons like command_not_found. If this fails, an error
// will have been printed.
parse_execution_result_t pop_result =
this->populate_job_from_job_node(job.get(), job_node, associated_block);
// Clean up the job on failure or cancellation.
bool populated_job = (pop_result == parse_execution_success);
if (!populated_job || this->should_cancel_execution(associated_block)) {
assert(parser->current_block()->job == job);
parser->current_block()->job = NULL;
populated_job = false;
}
assert(libdata.caller_job_id == job->job_id && "Caller job ID unexpectedly changed");
parser->libdata().caller_job_id = saved_caller_jid;
// Store time it took to 'parse' the command.
if (profile_item != NULL) {
parse_time = get_time();
}
// Clean up the job on failure or cancellation.
bool populated_job = (pop_result == parse_execution_success);
if (populated_job) {
// Success. Give the job to the parser - it will clean it up.
parser->job_add(job);

View file

@ -138,7 +138,6 @@ void parser_t::push_block_int(block_t *new_current) {
new_current->skip = false;
}
new_current->job = nullptr;
new_current->loop_status = LOOP_NORMAL;
// Push it onto our stack. This acquires ownership because of unique_ptr.

View file

@ -67,8 +67,6 @@ struct block_t {
bool skip{false};
/// Status for the current loop block. Can be any of the values from the loop_status enum.
enum loop_status_t loop_status { LOOP_NORMAL };
/// The job that is currently evaluated in the specified block.
shared_ptr<job_t> job{};
/// Name of file that created this block. This string is intern'd.
const wchar_t *src_filename{nullptr};
/// Line number where this block was created.
@ -159,6 +157,10 @@ struct library_data_t {
/// Whether we are currently cleaning processes.
bool is_cleaning_procs{false};
/// The job id of the job being populated.
/// This supports the '--on-job-exit caller' feature.
job_id_t caller_job_id{-1};
};
class parser_t : public std::enable_shared_from_this<parser_t> {