Files
hak/t/sysproc-02.hak

65 lines
1.6 KiB
Plaintext

## the exit handle: waiting for a child to terminate with no polling at all.
##
## sys.popen's slot 4 is a handle that becomes readable when the child exits,
## so it is waited on exactly like a pipe. Where the platform has no such
## facility the slot is nil and this test reports that it was skipped.
fun chk(ok msg) {
if ok { printf "OK: %s\n" msg } \
else { printf "ERROR: %s\n" msg }
}
iosem := (core.sem-new)
tmo := (core.sem-new)
sg := (core.semgr-new)
core.semgr-add sg iosem
core.semgr-add sg tmo
fin := (core.sem-new)
p := (sys.popen "sleep 1; exit 5" "r")
proc := (core.basicAt p 0)
xh := (core.basicAt p 4)
if (nil? xh) {
printf "OK: no exit handle on this platform - skipped\n"
sys.pclose proc
} \
else {
ticks := 0
status := -2
fun waiter() {
| s |
core.sem-signal tmo 20 0
core.sem-signal-on-input iosem xh
s := (core.semgr-wait sg)
core.sem-unsignal iosem
core.sem-unsignal tmo
if (eqv? s tmo) { status := -1 } \
else { status := (sys.pwait proc) }
core.sem-signal fin
return 0
}
fun ticker() {
## the waiter is parked on the exit handle by now; these ticks only
## happen if the VM went on scheduling instead of blocking
while (< ticks 4) {
ticks := (+ ticks 1)
core.yield
}
}
chk (integer? xh) "sys.popen hands back an exit handle"
core.fork waiter
core.fork ticker
core.sem-wait fin
chk (= ticks 4) "other coprocesses ran while the child was alive"
chk (= status 5) "the exit handle woke the waiter and the status was read"
## it belongs to the process handle, so pclose takes it away
sys.pclose proc
chk true "pclose released the exit handle with the group"
}