fix(app): #343 — a wounded render loop defers the native release instead of throwing over the real failure
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Root cause pinned by IL-decompiling Silk.NET.Windowing.Common: ViewImplementationBase._inRenderLoop is set at DoRender/DoUpdate entry and cleared ONLY on normal return, so a throwing frame callback leaves it armed forever and any later Dispose -> Reset throws "You cannot call Reset inside of the render loop", exit 82, replacing the original wounding exception in the report. The fix mirrors Silk's own bracket exactly: GameWindow._renderLoopArmed set at OnUpdate/OnRender entry, cleared only on their normal return — deliberately NOT in a finally, so it tracks the wound the same way Silk's private field does. ReleaseNativeWindow checks it before disposing: armed -> best-effort Close() (swallowed so it can never become the reported failure), no Dispose, and a new terminal status CompleteWithDeferredNativeRelease with Error kept null — the original exception stays the primary report. Healthy paths (OnClosing's in-loop completion, Run()'s tail release) are byte-unchanged, and the new PublishNativeWindow parameters default to null so every existing caller and test behaves identically. Sabotage: disabling the armed-check flipped the deferral test to Expected CompleteWithDeferredNativeRelease / Actual Complete — the guard is what the test exercises. Clean-room suite 11,262 / 6 / 1, the 1 being #340's documented load flake (passed standalone; second recorded firing noted in its entry). Queue: #344 done, #343 done; next #345's instrumented mechanism session, then #341's boundary hunt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
52bdf4df71
commit
6c6664a685
4 changed files with 194 additions and 10 deletions
|
|
@ -257,7 +257,19 @@ mid-flight-teleport-only. Next-session queue: #344, #343, then S4b/S6.
|
|||
|
||||
## #343 — Shutdown after a wounded render loop: Silk Reset called inside the render loop, exit 82
|
||||
|
||||
**Status:** OPEN. LOW-MEDIUM — only reachable after a render-frame exception
|
||||
**Status:** FIXED 2026-08-08. Root cause pinned by IL-decompiling Silk:
|
||||
`ViewImplementationBase._inRenderLoop` is cleared only on a frame callback's
|
||||
NORMAL return, so a throwing callback leaves it armed forever and the
|
||||
disposal's `Reset()` throws. The fix mirrors that bracket exactly
|
||||
(`GameWindow._renderLoopArmed`, deliberately not cleared in a finally),
|
||||
and `ReleaseNativeWindow` defers when armed: best-effort `Close()`, no
|
||||
`Dispose()`, new terminal status `CompleteWithDeferredNativeRelease` with
|
||||
`Error` kept null so the ORIGINAL wounding exception remains the primary
|
||||
report. Sabotage-verified; healthy paths byte-unchanged. Clean-room suite
|
||||
11,262 passed / 6 skipped / 1 failed = #340's documented flake, which
|
||||
passed standalone (its second recorded firing).
|
||||
|
||||
**Original status:** OPEN. LOW-MEDIUM — only reachable after a render-frame exception
|
||||
(#339's crash was the trigger), but it turns a diagnosable failure into an
|
||||
`AbandonedIncomplete` shutdown. `GameWindowLifetime.ReleaseNativeWindow:294`
|
||||
calls `ViewImplementationBase.Dispose` → `Reset` while the render loop is
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue