fix(capture/vdisplay): descriptor-following defers while a topology reassert is in flight

The exclusive-topology reassert's forced re-commit transiently bounces the
virtual display's mode; the descriptor poller can sample that EVICTION state
and recreate the ring at a mode the recovery chain is about to undo (field
log 2026-07-27 10:30:44Z: hdr=true → false → recreate → recovery restores
true → second recreate). New pf-win-display::topology_churn latch (deadline
semantics — self-expiring, so a lost release can never wedge descriptor-
following off): the watchdog holds it for interval+3s each fighting round and
releases on "stable again"; poll_display_hdr consumes samples but acts on
nothing while held — which also keeps the negotiated-depth pin-back from
issuing a CCD write mid-eviction, where it would fight the reassert itself.
The deliberate recreate_ring_in_place recovery path is unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-27 15:37:05 +02:00
co-authored by Claude Fable 5
parent 9e1a686795
commit 1945052e66
4 changed files with 99 additions and 0 deletions
@@ -865,11 +865,21 @@ impl VirtualDisplayManager {
reasserts = fighting,
"exclusive topology stable again — no non-managed display active"
);
// Close the churn window early — descriptor-following resumes now
// instead of waiting out the hold's self-expiry.
pf_win_display::topology_churn::release();
}
fighting = 0;
continue;
}
fighting += 1;
// Announce the churn BEFORE evicting: every descriptor the capturer's poller
// samples from here until "stable again" (or self-expiry) is potentially the
// TRANSIENT eviction state — acting on it would recreate the ring at a mode
// the recovery chain is about to undo (the field hdr=true→false→true double
// recreate). Window = watchdog interval + recovery/debounce margin, refreshed
// every fighting round.
pf_win_display::topology_churn::hold(interval + Duration::from_secs(3));
match fighting {
1..=3 => tracing::warn!(
survivors,