mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-08 20:32:56 +03:00
Shell: Ignore SIGCHLD after a few unsuccessful attempts at handling it
As noted by the comment, a stray SIGCHLD can make the shell go into an infinite loop, pretend the signal doesn't exist after trying 10 times in 5ms.
This commit is contained in:
parent
eb4ea45822
commit
d338d2b59b
Notes:
sideshowbarker
2024-07-17 09:58:27 +09:00
Author: https://github.com/alimpfard Commit: https://github.com/SerenityOS/serenity/commit/d338d2b59b Pull-request: https://github.com/SerenityOS/serenity/pull/14372
@ -2082,13 +2082,26 @@ void Shell::notify_child_event()
|
||||
// The child might still be alive (and even running) when this signal is dispatched to us
|
||||
// so just...repeat until we find a suitable child.
|
||||
// This, of course, will mean that someone can send us a SIGCHILD and we'd be spinning here
|
||||
// until the next child event we can actually handle.
|
||||
// until the next child event we can actually handle, so stop after spending a total of 5110us (~5ms) on it.
|
||||
bool found_child = false;
|
||||
do {
|
||||
size_t const max_tries = 10;
|
||||
size_t valid_attempts = max_tries;
|
||||
useconds_t backoff_usec = 20;
|
||||
int backoff_multiplier = 2;
|
||||
|
||||
for (;;) {
|
||||
if (found_child || --valid_attempts == 0)
|
||||
break;
|
||||
|
||||
// Ignore stray SIGCHLD when there are no jobs.
|
||||
if (jobs.is_empty())
|
||||
return;
|
||||
|
||||
if (valid_attempts < max_tries - 1) {
|
||||
usleep(backoff_usec);
|
||||
backoff_usec *= backoff_multiplier;
|
||||
}
|
||||
|
||||
for (auto& it : jobs) {
|
||||
auto job_id = it.key;
|
||||
auto& job = *it.value;
|
||||
@ -2141,7 +2154,7 @@ void Shell::notify_child_event()
|
||||
for (auto job_id : disowned_jobs) {
|
||||
jobs.remove(job_id);
|
||||
}
|
||||
} while (!found_child);
|
||||
}
|
||||
}
|
||||
|
||||
Shell::Shell()
|
||||
|
Loading…
Reference in New Issue
Block a user