Make $pipestatus thread safe and other misc cleanup

This commit is contained in:
ridiculousfish 2019-02-10 13:43:02 -08:00
parent 2c8abdf5cb
commit 2c3214cabd
7 changed files with 24 additions and 33 deletions

View File

@ -1392,13 +1392,13 @@ maybe_t<env_var_t> env_stack_t::get(const wcstring &key, env_mode_flags_t mode)
if (history) history->get_history(result); if (history) history->get_history(result);
return env_var_t(L"history", result); return env_var_t(L"history", result);
} else if (key == L"pipestatus") { } else if (key == L"pipestatus") {
const auto& js = proc_get_last_job_statuses(); const auto js = proc_get_last_job_statuses();
wcstring_list_t result; wcstring_list_t result;
result.reserve(js->size()); result.reserve(js.size());
for (auto&& i : *js) { for (int i : js) {
result.emplace_back(to_string(i)); result.push_back(to_string(i));
} }
return env_var_t(L"pipestatus", result); return env_var_t(L"pipestatus", std::move(result));
} else if (key == L"status") { } else if (key == L"status") {
return env_var_t(L"status", to_string(proc_get_last_status())); return env_var_t(L"status", to_string(proc_get_last_status()));
} else if (key == L"umask") { } else if (key == L"umask") {

View File

@ -275,7 +275,7 @@ static void event_fire_internal(const event_t &event) {
// non-interactive. // non-interactive.
proc_push_interactive(0); proc_push_interactive(0);
int prev_status = proc_get_last_status(); int prev_status = proc_get_last_status();
const auto& saved_job_statuses = proc_get_last_job_statuses(); auto saved_job_statuses = proc_get_last_job_statuses();
parser_t &parser = parser_t::principal_parser(); parser_t &parser = parser_t::principal_parser();
event_block_t *b = parser.push_block<event_block_t>(event); event_block_t *b = parser.push_block<event_block_t>(event);

View File

@ -1066,7 +1066,7 @@ static int exec_subshell_internal(const wcstring &cmd, parser_t &parser, wcstrin
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
bool prev_subshell = is_subshell; bool prev_subshell = is_subshell;
const int prev_status = proc_get_last_status(); const int prev_status = proc_get_last_status();
const auto& prev_job_statuses = proc_get_last_job_statuses(); auto prev_job_statuses = proc_get_last_job_statuses();
bool split_output = false; bool split_output = false;
const auto ifs = parser.vars().get(L"IFS"); const auto ifs = parser.vars().get(L"IFS");

View File

@ -367,7 +367,7 @@ static void input_mapping_execute(const input_mapping_t &m, bool allow_commands)
// FIXME(snnw): if commands add stuff to input queue (e.g. commandline -f execute), we won't // FIXME(snnw): if commands add stuff to input queue (e.g. commandline -f execute), we won't
// see that until all other commands have also been run. // see that until all other commands have also been run.
int last_status = proc_get_last_status(); int last_status = proc_get_last_status();
const auto& last_job_statuses = proc_get_last_job_statuses(); auto last_job_statuses = proc_get_last_job_statuses();
for (const wcstring &cmd : m.commands) { for (const wcstring &cmd : m.commands) {
parser_t::principal_parser().eval(cmd, io_chain_t(), TOP); parser_t::principal_parser().eval(cmd, io_chain_t(), TOP);
} }

View File

@ -717,8 +717,9 @@ parse_execution_result_t parse_execution_context_t::handle_command_not_found(
} }
// Set the last proc status appropriately. // Set the last proc status appropriately.
proc_set_last_status(err_code == ENOENT ? STATUS_CMD_UNKNOWN : STATUS_NOT_EXECUTABLE); int status = err_code == ENOENT ? STATUS_CMD_UNKNOWN : STATUS_NOT_EXECUTABLE;
proc_set_last_job_statuses(proc_get_last_status()); proc_set_last_status(status);
proc_set_last_job_statuses({status});
return parse_execution_errored; return parse_execution_errored;
} }

View File

@ -54,7 +54,7 @@
static int last_status = 0; static int last_status = 0;
/// Statuses of last job's processes to exit - ensure we start off with one entry of 0. /// Statuses of last job's processes to exit - ensure we start off with one entry of 0.
static std::shared_ptr<std::vector<int>> last_job_statuses = std::make_shared<std::vector<int>>(1); static owning_lock<std::vector<int>> last_job_statuses{std::vector<int>(1u, 0)};
/// The signals that signify crashes to us. /// The signals that signify crashes to us.
static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS}; static const int crashsignals[] = {SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGSYS};
@ -144,30 +144,21 @@ int proc_get_last_status() { return last_status; }
void proc_set_last_job_statuses(const job_t &last_job) { void proc_set_last_job_statuses(const job_t &last_job) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
auto ljs = std::make_shared<std::vector<int>>(); std::vector<int> ljs;
ljs->reserve(last_job.processes.size()); ljs.reserve(last_job.processes.size());
for (auto &&p : last_job.processes) { for (const auto &p : last_job.processes) {
ljs->emplace_back(p->pid ? proc_format_status(p->status) : p->status); ljs.push_back(p->pid ? proc_format_status(p->status) : p->status);
} }
last_job_statuses = std::move(ljs); proc_set_last_job_statuses(std::move(ljs));
} }
void proc_set_last_job_statuses(std::shared_ptr<std::vector<int>> job_statuses) { void proc_set_last_job_statuses(std::vector<int> statuses) {
ASSERT_IS_MAIN_THREAD(); ASSERT_IS_MAIN_THREAD();
last_job_statuses = std::move(job_statuses); auto vals = last_job_statuses.acquire();
*vals = std::move(statuses);
} }
void proc_set_last_job_statuses(const int job_status) { std::vector<int> proc_get_last_job_statuses() { return *last_job_statuses.acquire(); }
ASSERT_IS_MAIN_THREAD();
auto ljs = std::make_shared<std::vector<int>>(1);
(*ljs)[0] = job_status;
last_job_statuses = std::move(ljs);
}
std::shared_ptr<std::vector<int>> proc_get_last_job_statuses() {
ASSERT_IS_MAIN_THREAD();
return last_job_statuses;
}
// Basic thread safe job IDs. The vector consumed_job_ids has a true value wherever the job ID // Basic thread safe job IDs. The vector consumed_job_ids has a true value wherever the job ID
// corresponding to that slot is in use. The job ID corresponding to slot 0 is 1. // corresponding to that slot is in use. The job ID corresponding to slot 0 is 1.

View File

@ -418,11 +418,10 @@ int proc_get_last_status();
/// Sets the status of the last job's processes to exit from last_job. /// Sets the status of the last job's processes to exit from last_job.
void proc_set_last_job_statuses(const job_t &last_job); void proc_set_last_job_statuses(const job_t &last_job);
void proc_set_last_job_statuses(std::shared_ptr<std::vector<int>>); void proc_set_last_job_statuses(std::vector<int> statuses);
void proc_set_last_job_statuses(const int); // for errors where pipe is unknown
/// Returns the status of the last job's processes to exit. /// Returns the statuses of the last job's processes to exit.
std::shared_ptr<std::vector<int>> proc_get_last_job_statuses(); std::vector<int> proc_get_last_job_statuses();
/// Notify the user about stopped or terminated jobs. Delete terminated jobs from the job list. /// Notify the user about stopped or terminated jobs. Delete terminated jobs from the job list.
/// ///