mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +00:00
Only send JOB_EXIT after the job has been actually erased
This commit is contained in:
parent
06adb1dc38
commit
7f5e58ae69
1 changed files with 14 additions and 10 deletions
24
src/proc.cpp
24
src/proc.cpp
|
@ -461,7 +461,7 @@ static bool process_clean_after_marking(bool allow_interactive) {
|
|||
ASSERT_IS_MAIN_THREAD();
|
||||
bool found = false;
|
||||
|
||||
// this function may fire an event handler, we do not want to call ourselves recursively (to
|
||||
// This function may fire an event handler, we do not want to call ourselves recursively (to
|
||||
// avoid infinite recursion).
|
||||
static bool locked = false;
|
||||
if (locked) {
|
||||
|
@ -469,11 +469,13 @@ static bool process_clean_after_marking(bool allow_interactive) {
|
|||
}
|
||||
locked = true;
|
||||
|
||||
// this may be invoked in an exit handler, after the TERM has been torn down
|
||||
// don't try to print in that case (#3222)
|
||||
// This may be invoked in an exit handler, after the TERM has been torn down
|
||||
// Don't try to print in that case (#3222)
|
||||
const bool interactive = allow_interactive && cur_term != NULL;
|
||||
|
||||
static std::vector<job_t *> erase_list;
|
||||
// If we ever drop the `static bool locked` above, this should be changed to a local or
|
||||
// thread-local vector instead of a static vector. It is only static to reduce heap allocations.
|
||||
static std::vector<shared_ptr<job_t>> erase_list;
|
||||
const bool only_one_job = jobs().size() == 1;
|
||||
for (const auto &j : jobs()) {
|
||||
// If we are reaping only jobs who do not need status messages sent to the console, do not
|
||||
|
@ -565,9 +567,8 @@ static bool process_clean_after_marking(bool allow_interactive) {
|
|||
if (j->pgid != INVALID_PID) {
|
||||
proc_fire_event(L"JOB_EXIT", event_type_t::exit, -j->pgid, 0);
|
||||
}
|
||||
proc_fire_event(L"JOB_EXIT", event_type_t::job_exit, j->job_id, 0);
|
||||
|
||||
erase_list.push_back(j.get());
|
||||
erase_list.push_back(j);
|
||||
} else if (j->is_stopped() && !j->get_flag(job_flag_t::NOTIFIED)) {
|
||||
// Notify the user about newly stopped jobs.
|
||||
if (!j->get_flag(job_flag_t::SKIP_NOTIFICATION)) {
|
||||
|
@ -585,10 +586,7 @@ static bool process_clean_after_marking(bool allow_interactive) {
|
|||
auto to_erase = erase_list.begin();
|
||||
jobs().erase(std::remove_if(jobs().begin(), jobs().end(),
|
||||
[&to_erase](const shared_ptr<job_t> &j) {
|
||||
if (to_erase == erase_list.end()) {
|
||||
return false;
|
||||
}
|
||||
if (*to_erase == j.get()) {
|
||||
if (to_erase != erase_list.end() && *to_erase == j) {
|
||||
++to_erase;
|
||||
return true;
|
||||
}
|
||||
|
@ -606,6 +604,12 @@ static bool process_clean_after_marking(bool allow_interactive) {
|
|||
&& "Not all jobs slated for erasure have been erased!");
|
||||
}
|
||||
}
|
||||
|
||||
// Only now notify any listeners of the job exit, so that the contract isn't violated
|
||||
for (const auto &j : erase_list) {
|
||||
proc_fire_event(L"JOB_EXIT", event_type_t::job_exit, j->job_id, 0);
|
||||
}
|
||||
|
||||
erase_list.clear();
|
||||
|
||||
if (found) {
|
||||
|
|
Loading…
Reference in a new issue