container: spin instead of block on wait4 ECHILD
All checks were successful
Test / Create distribution (push) Successful in 36s
Test / Sandbox (push) Successful in 2m44s
Test / Sandbox (race detector) (push) Successful in 4m43s
Test / Hpkg (push) Successful in 4m57s
Test / Hakurei (push) Successful in 5m2s
Test / Hakurei (race detector) (push) Successful in 6m27s
Test / Flake checks (push) Successful in 1m27s

Blocking prevents further wait4 processing causing ops to never receive their signals.

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
Ophestra 2025-12-08 22:56:13 +09:00
parent 96dd7abd80
commit dafe9f8efc
Signed by: cat
SSH Key Fingerprint: SHA256:gQ67O0enBZ7UdZypgtspB2FDM1g3GVw8nX0XSdcFw8Q

View File

@ -11,6 +11,7 @@ import (
"slices" "slices"
"strconv" "strconv"
"sync" "sync"
"sync/atomic"
. "syscall" . "syscall"
"time" "time"
@ -368,8 +369,8 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
// when there are no longer any processes left to reap // when there are no longer any processes left to reap
info := make(chan winfo, 1) info := make(chan winfo, 1)
// closed when the initial process has started // whether initial process has started
initialProcessStarted := make(chan struct{}) var initialProcessStarted atomic.Bool
k.new(func(k syscallDispatcher) { k.new(func(k syscallDispatcher) {
k.lockOSThread() k.lockOSThread()
@ -413,11 +414,10 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
if !errors.Is(err, ECHILD) { if !errors.Is(err, ECHILD) {
k.printf(msg, "unexpected wait4 response: %v", err) k.printf(msg, "unexpected wait4 response: %v", err)
} else if initialProcessStarted != nil { } else if !initialProcessStarted.Load() {
// initial process has not yet been reached and all daemons // initial process has not yet been reached and all daemons
// terminated or none were started in the first place // terminated or none were started in the first place
<-initialProcessStarted time.Sleep(500 * time.Microsecond)
initialProcessStarted = nil
goto wait4 goto wait4
} }
@ -458,7 +458,7 @@ func initEntrypoint(k syscallDispatcher, msg message.Msg) {
if err := k.start(cmd); err != nil { if err := k.start(cmd); err != nil {
k.fatalf(msg, "%v", err) k.fatalf(msg, "%v", err)
} }
close(initialProcessStarted) initialProcessStarted.Store(true)
// handle signals to dump withheld messages // handle signals to dump withheld messages
sig := make(chan os.Signal, 2) sig := make(chan os.Signal, 2)