Make is_event and other globals part of parser_t libdata

This commit is contained in:
ridiculousfish 2019-05-12 18:02:57 -07:00
parent c44dae2d73
commit 508c3a8005
10 changed files with 41 additions and 36 deletions

View file

@ -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;
}

View file

@ -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: {

View file

@ -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<decltype(is_event)> 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<decltype(ld.is_event)> 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();

View file

@ -1130,7 +1130,7 @@ bool exec_job(parser_t &parser, shared_ptr<job_t> 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;

View file

@ -1227,6 +1227,7 @@ parse_execution_result_t parse_execution_context_t::run_1_job(tnode_t<g::job> jo
}
shared_ptr<job_t> job = std::make_shared<job_t>(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<g::job> 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

View file

@ -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 {

View file

@ -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<parser_t> {

View file

@ -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; }

View file

@ -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<shared_ptr<job_t>> job_list_t;

View file

@ -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);