Жёсткого приоритета нет. Сейчас оба fd level-triggered, а на timer-path дополнительно проверяется g_child_exited и существование PGID через kill(-pgid, 0). Но да, на самой границе есть race: SIGCHLD уже может быть pending, а timerfd обработаться первым. Тут логичнее перед escalation сделать ещё один non-blocking reap - хороший кейс, спасибо.
Да, тут я скорее неточно сформулировал - под "разойдутся" имел в виду не сам алгоритм, а низкоуровневую реализацию - без libc ожидал заметно больше arch-specific кода.
Кое-где различия действительно есть: например, на amd64 spawn идёт через fork, на arm64 - через clone(SIGCHLD, ...), плюс разные syscall ABI и обвязка. Но сама state machine - signalfd/epoll, reaping по SIGCHLD, forwarding в PGID, grace timer и restart - в итоге осталась почти один в один.
Жёсткого приоритета нет. Сейчас оба fd level-triggered, а на timer-path дополнительно проверяется
g_child_exitedи существование PGID черезkill(-pgid, 0).Но да, на самой границе есть race:
SIGCHLDуже может быть pending, аtimerfdобработаться первым. Тут логичнее перед escalation сделать ещё один non-blocking reap - хороший кейс, спасибо.Да, тут я скорее неточно сформулировал - под "разойдутся" имел в виду не сам алгоритм, а низкоуровневую реализацию - без libc ожидал заметно больше arch-specific кода.
Кое-где различия действительно есть: например, на amd64 spawn идёт через
fork, на arm64 - черезclone(SIGCHLD, ...), плюс разные syscall ABI и обвязка. Но сама state machine -signalfd/epoll, reaping поSIGCHLD, forwarding в PGID, grace timer и restart - в итоге осталась почти один в один.