From 508c3a800570ea91976af80f9b79150ec2e0239f Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Sun, 12 May 2019 18:02:57 -0700 Subject: [PATCH] Make is_event and other globals part of parser_t libdata --- src/builtin_function.cpp | 2 +- src/builtin_status.cpp | 6 +++--- src/event.cpp | 17 +++++++++++++---- src/exec.cpp | 6 +++--- src/parse_execution.cpp | 5 +++-- src/parser.cpp | 8 ++++---- src/parser.h | 13 +++++++++++++ src/proc.cpp | 5 ----- src/proc.h | 13 ------------- src/reader.cpp | 2 +- 10 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/builtin_function.cpp b/src/builtin_function.cpp index 9bc3a2f5f..94df2c21d 100644 --- a/src/builtin_function.cpp +++ b/src/builtin_function.cpp @@ -92,7 +92,7 @@ static int parse_cmd_opts(function_cmd_opts_t &opts, int *optind, //!OCLINT(hig if ((opt == 'j') && (wcscasecmp(w.woptarg, L"caller") == 0)) { job_id_t job_id = -1; - if (is_subshell) { + if (parser.libdata().is_subshell) { job_id = parser.libdata().caller_job_id; } diff --git a/src/builtin_status.cpp b/src/builtin_status.cpp index e800ac1d2..25fe787cf 100644 --- a/src/builtin_status.cpp +++ b/src/builtin_status.cpp @@ -389,17 +389,17 @@ int builtin_status(parser_t &parser, io_streams_t &streams, wchar_t **argv) { } case STATUS_IS_COMMAND_SUB: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = !is_subshell; + retval = parser.libdata().is_subshell ? 0 : 1; break; } case STATUS_IS_BLOCK: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = !is_block; + retval = parser.libdata().is_block ? 0 : 1; break; } case STATUS_IS_BREAKPOINT: { CHECK_FOR_UNEXPECTED_STATUS_ARGS(opts.status_cmd) - retval = !is_breakpoint; + retval = parser.libdata().is_breakpoint ? 0 : 1; break; } case STATUS_IS_LOGIN: { diff --git a/src/event.cpp b/src/event.cpp index 57975bb7f..e42a85921 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -248,8 +248,9 @@ bool event_is_signal_observed(int sig) { /// allocated/initialized unless needed. static void event_fire_internal(const event_t &event) { ASSERT_IS_MAIN_THREAD(); - assert(is_event >= 0 && "is_event should not be negative"); - scoped_push inc_event{&is_event, is_event + 1}; + auto &ld = parser_t::principal_parser().libdata(); + assert(ld.is_event >= 0 && "is_event should not be negative"); + scoped_push inc_event{&ld.is_event, ld.is_event + 1}; // Capture the event handlers that match this event. event_handler_list_t fire; @@ -293,9 +294,13 @@ static void event_fire_internal(const event_t &event) { /// Handle all pending signal events. void event_fire_delayed() { - ASSERT_IS_MAIN_THREAD(); + // Hack: only allow events on the main thread. + // TODO: rationalize how events work with multiple threads. + if (!is_main_thread()) return; + + auto &parser = parser_t::principal_parser(); // Do not invoke new event handlers from within event handlers. - if (is_event) return; + if (parser.libdata().is_event) return; event_list_t to_send; to_send.swap(blocked); @@ -330,6 +335,10 @@ void event_enqueue_signal(int signal) { } void event_fire(const event_t &event) { + // Hack: only allow events on the main thread. + // TODO: rationalize how events work with multiple threads. + if (!is_main_thread()) return; + // Fire events triggered by signals. event_fire_delayed(); diff --git a/src/exec.cpp b/src/exec.cpp index 2dcca1198..067f9eb03 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -1130,7 +1130,7 @@ bool exec_job(parser_t &parser, shared_ptr j) { static int exec_subshell_internal(const wcstring &cmd, parser_t &parser, wcstring_list_t *lst, bool apply_exit_status, bool is_subcmd) { ASSERT_IS_MAIN_THREAD(); - bool prev_subshell = is_subshell; + bool prev_subshell = parser.libdata().is_subshell; auto prev_statuses = parser.get_last_statuses(); bool split_output = false; @@ -1139,7 +1139,7 @@ static int exec_subshell_internal(const wcstring &cmd, parser_t &parser, wcstrin split_output = true; } - is_subshell = true; + parser.libdata().is_subshell = true; auto subcommand_statuses = statuses_t::just(-1); // assume the worst // IO buffer creation may fail (e.g. if we have too many open files to make a pipe), so this may @@ -1165,7 +1165,7 @@ static int exec_subshell_internal(const wcstring &cmd, parser_t &parser, wcstrin parser.set_last_statuses(std::move(prev_statuses)); } - is_subshell = prev_subshell; + parser.libdata().is_subshell = prev_subshell; if (lst == NULL || !buffer) { return subcommand_statuses.status; diff --git a/src/parse_execution.cpp b/src/parse_execution.cpp index 8ac906ab8..fc6ab1b71 100644 --- a/src/parse_execution.cpp +++ b/src/parse_execution.cpp @@ -1227,6 +1227,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t jo } shared_ptr job = std::make_shared(acquire_job_id(), block_io, parent_job); + auto &ld = parser_t::principal_parser().libdata(); job->tmodes = tmodes; auto job_control_mode = get_job_control_mode(); job->set_flag(job_flag_t::JOB_CONTROL, @@ -1235,10 +1236,10 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t jo job->set_flag(job_flag_t::FOREGROUND, !job_node_is_background(job_node)); - job->set_flag(job_flag_t::TERMINAL, job->get_flag(job_flag_t::JOB_CONTROL) && !is_event); + job->set_flag(job_flag_t::TERMINAL, job->get_flag(job_flag_t::JOB_CONTROL) && !ld.is_event); job->set_flag(job_flag_t::SKIP_NOTIFICATION, - is_subshell || is_block || is_event || !shell_is_interactive()); + ld.is_subshell || ld.is_block || ld.is_event || !shell_is_interactive()); // 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 diff --git a/src/parser.cpp b/src/parser.cpp index c3fe487ff..d38c8f301 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -145,11 +145,11 @@ void parser_t::push_block_int(block_t *new_current) { // Types TOP and SUBST are not considered blocks for the purposes of `status is-block`. if (type != TOP && type != SUBST) { - is_block = true; + libdata().is_block = true; } if (type == BREAKPOINT) { - is_breakpoint = true; + libdata().is_breakpoint = true; } if (new_current->type() != TOP) { @@ -182,7 +182,7 @@ void parser_t::pop_block(const block_t *expected) { break; } } - is_block = new_is_block; + libdata().is_block = new_is_block; // Are we still in a breakpoint? bool new_is_breakpoint = false; @@ -193,7 +193,7 @@ void parser_t::pop_block(const block_t *expected) { break; } } - is_breakpoint = new_is_breakpoint; + libdata().is_breakpoint = new_is_breakpoint; } const wchar_t *parser_t::get_block_desc(int block) const { diff --git a/src/parser.h b/src/parser.h index ee1e1d79e..e1f1af04e 100644 --- a/src/parser.h +++ b/src/parser.h @@ -161,6 +161,19 @@ struct library_data_t { /// The job id of the job being populated. /// This supports the '--on-job-exit caller' feature. job_id_t caller_job_id{-1}; + + /// Whether we are running a subshell command. + bool is_subshell{false}; + + /// Whether we are running a block of commands. + bool is_block{false}; + + /// Whether we are running due to a `breakpoint` command. + bool is_breakpoint{false}; + + /// Whether we are running an event handler. This is not a bool because we keep count of the + /// event nesting level. + int is_event{0}; }; class parser_t : public std::enable_shared_from_this { diff --git a/src/proc.cpp b/src/proc.cpp index cb0284eaa..a20174bf0 100644 --- a/src/proc.cpp +++ b/src/proc.cpp @@ -52,11 +52,6 @@ /// The signals that signify crashes to us. static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS}; -bool is_subshell = false; -bool is_block = false; -bool is_breakpoint = false; -int is_event = 0; - static relaxed_atomic_bool_t s_is_interactive_session{false}; bool is_interactive_session() { return s_is_interactive_session; } void set_interactive_session(bool flag) { s_is_interactive_session = flag; } diff --git a/src/proc.h b/src/proc.h index 24f1336d3..eb12e5b92 100644 --- a/src/proc.h +++ b/src/proc.h @@ -417,15 +417,6 @@ class job_t { /// Whether we are reading from the keyboard right now. bool shell_is_interactive(); -/// Whether we are running a subshell command. -extern bool is_subshell; - -/// Whether we are running a block of commands. -extern bool is_block; - -/// Whether we are running due to a `breakpoint` command. -extern bool is_breakpoint; - /// Whether this shell is attached to the keyboard at all. bool is_interactive_session(); void set_interactive_session(bool flag); @@ -440,10 +431,6 @@ void mark_login(); bool no_exec(); void mark_no_exec(); -/// Whether we are running an event handler. This is not a bool because we keep count of the event -/// nesting level. -extern int is_event; - // List of jobs. typedef std::deque> job_list_t; diff --git a/src/reader.cpp b/src/reader.cpp index 203bfd2e9..02836ec8d 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2264,7 +2264,7 @@ static int read_i() { event_fire_generic(L"fish_prompt"); run_count++; - if (is_breakpoint && function_exists(DEBUG_PROMPT_FUNCTION_NAME, parser)) { + if (parser.libdata().is_breakpoint && function_exists(DEBUG_PROMPT_FUNCTION_NAME, parser)) { reader_set_left_prompt(DEBUG_PROMPT_FUNCTION_NAME); } else if (function_exists(LEFT_PROMPT_FUNCTION_NAME, parser)) { reader_set_left_prompt(LEFT_PROMPT_FUNCTION_NAME);