diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-10-02 14:43:15 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-10-02 14:43:15 +0100 |
| commit | f6be217fa12f794d225788e4a62ce60fd709c266 (patch) | |
| tree | fde0637fbf5290e3ed816523254d965609e784df /shell | |
| parent | 0496280c4589bf33192ab01ce052d66179e0ade3 (diff) | |
| download | busybox-w32-f6be217fa12f794d225788e4a62ce60fd709c266.tar.gz busybox-w32-f6be217fa12f794d225788e4a62ce60fd709c266.tar.bz2 busybox-w32-f6be217fa12f794d225788e4a62ce60fd709c266.zip | |
ash: wait builtin should block
It was found that the 'wait' shell builtin would use 100% of a core
when waiting for a process to terminate:
sleep 60 &
wait
This is a regression caused by commit bb8f6b688 (ash: fix slow
running when background job is present). See the commit message
and GitHub issue #434 for the long and involved history.
The problem is in the Windows implementation of waitproc() in ash.
The 'block' argument to waitproc() can take three values:
DOWAIT_NONBLOCK
DOWAIT_BLOCK
DOWAIT_CHILD_OR_SIG
The first two have obvious meanings. The third performs a non-
blocking wait(2) and if no PID is returned it waits for SIGCHLD.
So in effect it's a blocking wait.
The Windows implementation would perform a non-blocking wait(2)
but couldn't then wait for SIGCHLD, because Windows doesn't have
such a signal. As a result the 'wait' builtin would loop calling
waitproc().
To avoid this DOWAIT_CHILD_OR_SIG should be treated as a blocking
wait in waitproc().
(GitHub issue #529)
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/shell/ash.c b/shell/ash.c index 61f10d74e..ab8733729 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -5142,7 +5142,7 @@ waitproc(int block, int *status) | |||
| 5142 | 5142 | ||
| 5143 | return err; | 5143 | return err; |
| 5144 | #else | 5144 | #else |
| 5145 | int flags = block == DOWAIT_BLOCK ? 0 : WNOHANG; | 5145 | int flags = block == DOWAIT_NONBLOCK ? WNOHANG : 0; |
| 5146 | *status = 0; | 5146 | *status = 0; |
| 5147 | return waitpid(-1, status, flags); | 5147 | return waitpid(-1, status, flags); |
| 5148 | #endif | 5148 | #endif |
