pidwait waits for only half of the given processes
Apparently pidwait
waits for only half of the given processes.
bash example to reproduce:
$ for i in {2,4}; do sleep $i & done; time pidwait -u $LOGNAME sleep
[1] 8630
[2] 8631
[1]- Done sleep $i
real 0m2.005s
user 0m0.012s
sys 0m0.015s
You see that pidwait
takes only 2 seconds but it should take 4 seconds if it waited for the sleep 4
command.
strace
shows why this is:
pidfd_open(8659, 0) = 4
epoll_ctl(3, EPOLL_CTL_ADD, 4, {events=EPOLLIN|EPOLLET, data=0x4}) = 0
pidfd_open(8660, 0) = 5
epoll_ctl(3, EPOLL_CTL_ADD, 5, {events=EPOLLIN|EPOLLET, data=0x5}) = 0
epoll_wait(3, [{events=EPOLLIN, data=0x4}], 32, -1) = 1
epoll_wait(3, [{events=EPOLLIN|EPOLLHUP, data=0x4}], 32, -1) = 1
It seems that for each finished process there are 2 epoll events: one EPOLLIN
and one EPOLLIN|EPOLLHUP
. I suppose that EPOLLIN
occurs when the process has exited and EPOLLIN|EPOLLHUP
occurs when the process has been collected by wait
or waitpid
.
Since the pidwait
code merely counts the epoll events that have EPOLLIN set it counts every terminated process twice so that it only waits for half of the given processes.
BTW, the pidwait
manpage doesn't clearly specify if it waits for processes until they have exited or until they have been collected (it might be worth having a commandline option to distinguish between the two).
$ ps --info
BSD j OL_j
BSD l OL_l
BSD s OL_s
BSD u OL_u
BSD v OL_v
SysV -f (none)
SysV -fl (none)
SysV -j (none)
SysV -l (none)
procps-ng version 4.0.4
Compiled with: glibc 2.40, gcc 15.0
header_gap=-1 lines_to_next_header=1
screen_cols=129 screen_rows=48
personality=0x00000000 (from "unknown")
EUID=1000 TTY=136,7 page_size=4096
sizeof(proc_t)=8 sizeof(long)=8 sizeof(long)=8
archdefs: x86_64