wake/detector: bound the sleep-child fd claim to the sleep child (M3 scope)
ci/woodpecker/pr/ci Pipeline was successful

Round-4 review (rev-974, at b648079) found the corrected comment still
overclaiming, in the opposite direction from round 3. The sentence said the
orphaned sleep's exit closes "the last copy of the fd" and "the next start
succeeds". The sleep's exit closes ITS copy. Other inheritors of fd 9 -- the M1
adapter and M2 sink grandchildren -- are outside this M3-only patch and can keep
holding the flock, in which case the next start still refuses.

Reworded to bound the claim to what this patch actually removes: the sleep
child's hold, ending when its copy closes, within one poll interval. The
supervisor-retry cost is now stated as being on the sleep child's account
rather than as a general guarantee about the next start.

Comment-only. Non-comment lines 397 = 397; stripped sha256
d6ec89930d1a3f5f9550746fadfbc80bb44073db199c5be16f45e83ff49ce330 unchanged
across 60f8caf, da0c, b648079 and this commit. test-wake-detector.sh 13/13
including D4. bash -n clean. ShellCheck not available on this seat.

Refs #966
This commit is contained in:
Jason Woltje
2026-07-31 07:53:42 -05:00
parent b648079fad
commit c1954ea2ac
@@ -533,11 +533,13 @@ cmd_run() {
# keeps the single-instance flock (fd 9, taken at exec 9> above) alive after
# the detector parent dies. The lock is non-blocking (`flock -n`, above), so
# for as long as that sleep survives a replacement instance is REFUSED and
# exits rather than queueing. The window is BOUNDED by one poll interval
# (WAKE_DETECTOR_INTERVAL, default 30s): when the orphaned sleep exits the
# last copy of the fd closes and the next start succeeds. The cost is a
# restart window in which every supervisor retry fails — not a lock that
# nothing can ever reclaim.
# exits rather than queueing. This particular hold is BOUNDED by one poll
# interval (WAKE_DETECTOR_INTERVAL, default 30s): when the orphaned sleep
# exits its copy of fd 9 closes, ending this bounded sleep-child hold. It
# does NOT follow that the next start succeeds — other inheritors of fd 9
# (the M1 adapter, M2 sink grandchildren) are outside this patch's scope and
# can keep holding the flock. The cost this removes is a restart window in
# which every supervisor retry fails on the sleep child's account.
# `9>&-` closes ONLY the child's copy — the parent's lock is unaffected.
sleep "$interval" 9>&-
done