Skip to content

Fix four host faults the synthetic tests could never see - #27

Merged
whoisaldo merged 1 commit into
mainfrom
fix/host-supervisor-and-abr
Aug 27, 2026
Merged

Fix four host faults the synthetic tests could never see#27
whoisaldo merged 1 commit into
mainfrom
fix/host-supervisor-and-abr

Conversation

@whoisaldo

Copy link
Copy Markdown
Owner

More findings from the /code-review pass, each confirmed by reading the tree. They share a root cause for why CI is green: the synthetic capture backend starts instantly, never changes resolution, and never touches the virtual display.

The extended display could never come up. spawn_generation re-armed the running flag but left the watchdog heartbeat atomics holding the previous generation's timestamps, and the wedge check has no warm-up. Attaching the virtual display polls for up to 10s before the capture loop stamps its first heartbeat, so at 3s the watchdog judged the new generation by the old one's clock, killed it, and repeated until the storm brake parked the supervisor in Failed. The atomics are now stamped at spawn.

A superseded capture thread kept running. Stage threads are detached, so one blocked in the VDD poll or the ACCESS_LOST ladder outlives its generation — then re-reads the process-wide running flag, finds it true again for the next generation, and carries on. Two capture loops then fight over a DXGI duplication only one can hold, and the zombie's heartbeats mask the watchdog that would have caught it. Stage loops now stop when their own generation is superseded, which is what CURRENT_GENERATION existed for.

Lowering the bitrate slider did nothing. set_ceiling clamps the rung and reports changed: true, but the caller discarded that decision and used only on_report's — which returns unchanged for a clean report. The label moved; the encoder didn't, for the life of the pipeline. Both decisions now count.

A typed-in address counted as a viewer. client_connected only checked target_addr, which the GUI's Target IP field and the persisted target_ip both wrote. With nobody connected the capture loop skipped its idle throttle and ran flat out, and with Extended display selected the virtual monitor came up for an audience of none. In v2 the session is the only truth, so client_connected asks it — pinned by a new test. The Target IP control goes with it: media carries a session id from the handshake, so an address typed there could never have received a stream.

Gates

104 Rust tests (1 new), zero clippy warnings, E2E green including the crash-restart case that exercises a generation transition.

From the code-review pass over the merged revamp. Each is invisible to
CI because the synthetic capture backend starts instantly, never changes
resolution, and never touches the virtual display.

The extended display could never come up. spawn_generation re-armed the
running flag but left the watchdog heartbeat atomics holding the previous
generation's timestamps, and the wedge check has no warm-up. Attaching
the virtual display polls for up to 10 seconds before the capture loop
stamps its first heartbeat, so at 3 seconds the watchdog judged the new
generation by the old one's clock, killed it, and did the same to the
next five until the storm brake parked the supervisor in Failed. The
atomics are now stamped when a generation is spawned.

A superseded capture thread kept running. Stage threads are detached, so
one blocked in the virtual-display poll or the ACCESS_LOST retry ladder
outlives its generation; it then re-read the process-wide running flag,
found it true again for the NEXT generation, and carried on. Two capture
loops then fight over a DXGI duplication only one can hold, and the
zombie's heartbeats mask the watchdog that would have caught it. Stage
loops now stop when their own generation is superseded, which is what
CURRENT_GENERATION was there for.

Lowering the bitrate slider did nothing. set_ceiling clamps the current
rung and reports that it changed, but the caller discarded the decision
and used only on_report's, which returns unchanged for a clean report.
So the label moved and the encoder did not, for the life of the
pipeline. Both decisions now count.

A typed-in address counted as a viewer. client_connected only checked
target_addr, which the GUI's Target IP field and the persisted target_ip
both wrote — so with nobody connected the capture loop skipped its idle
throttle and ran flat out, and with Extended display selected the
virtual monitor came up for an audience of none. In v2 the session is
the only truth, so client_connected asks it. The Target IP control is
gone with it: media carries a session id from the handshake, so an
address typed there could never have received a stream.
@whoisaldo
whoisaldo merged commit f2c0523 into main Aug 27, 2026
4 checks passed
@whoisaldo
whoisaldo deleted the fix/host-supervisor-and-abr branch August 27, 2026 17:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant