fix(posix): drop oldest queued buffer instead of failing when waveOutWrite ring nears full #2115
No reviewers
Labels
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
No milestone
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2115
Loading…
Reference in a new issue
No description provided.
Delete branch "posix/waveout-ring-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
In
host/posix/win32_posix.c,waveOutWrite()still returnsMMSYSERR_ERRORoncew->count == 64. During shader compilation or heavy frame stalls on Linux, pending audio packets can fill the 64-entry ring and cause subsequentwaveOutWritecalls to fail or drop new buffers without recovering.When
w->count >= 60, this change retires the oldest queuedWAVEHDR(WHDR_INQUEUEcleared,WHDR_DONEpublished via__atomic_store_n(..., __ATOMIC_RELEASE)), advancesw->head, decrementsw->count, and resetsw->pos = 0so newest audio stays live without stalling callers.NVIDIA & Cross-Platform Compatibility
host/posix/win32_posix.conly compiles on POSIX/Linux hosts; Windowswinmmis unaffected.Files Changed
host/posix/win32_posix.cTest Plan / Verification
git apply --checkagainstmain(ca082bf).host/posix/win32_posix.c(clang -fsyntax-only -std=gnu11 -Wall -Wextra -Wno-macro-redefined -Wno-unused-parameter): 0 errors, 0 warnings.Thanks for looking at this. The shim change itself is sound, but I don't think it fixes what the description says, and it has no test.
What I checked on main:
waveOutWriteishost/nn_audio.c. It hasNBLOCKS 10headers and only reuses one after it readsWHDR_DONEon it ("the device is behind: this frame is dropped"). So at most 10 headers can ever be in the shim's ring. It never reaches 60, let alone 64, and the oldMMSYSERR_ERRORpath and this new branch are both unreachable from the game. Stalls during shader compilation are already handled in the caller: it drops the frame, and after 1.5 s of no completion it runsoutput_reopen()(#2190, merged). If you saw a real failure, which log line orwaveOutWriteerror did you get? That would tell us what is actually happening.WHDR_INQUEUEcleared andWHDR_DONEset under the ring mutex, so nothing can wait on it forever.posis reset under the same lock aswave_pull, so the ring is thread-safe. The drop could click if the oldest buffer was half-played, but it would only happen in an overflow that can't occur here.waveOutWritejust queues and never fails. Dropping at>= 60while the ring still has 4 free slots is an arbitrary threshold, and it keeps about 60 blocks of latency instead of catching up.count == 64; the patch changes the capacity to 60, which should be said.tests/audio_output_errors_test.c,tests/audio_wave_buffer_release_test.c).Unless there is a path I missed that submits more than 10 headers, I'd suggest closing this or reworking it around the real symptom. #1544 (Aux buffers) is unrelated to this ring.
I don't think the new branch can run. The only caller,
host/nn_audio.c, hasNBLOCKS 10headers (:738) and only resubmits one afterWHDR_DONE(:922), socountnever exceeds 10 and>= 60is never reached. If it did run, it would silently drop queued audio, whereas today a full ring returns an error the caller handles (:955-959). There's no use-after-free, since everything is underw->mu. Suggest closing unless there's a caller I've missed.github-sync referenced this pull request2026-11-12 06:22:54 +00:00