Skip to content

Audio/Linux: retain partial writes and stop failed pumps - #1508

Open
sebastian-griego wants to merge 1 commit into
bendlang:mainfrom
sebastian-griego:fix/linux-audio-progress
Open

sebastian-griego wants to merge 1 commit into
bendlang:mainfrom
sebastian-griego:fix/linux-audio-progress

Conversation

@sebastian-griego

Copy link
Copy Markdown

The Linux audio pump drops the unwritten part of a 256-frame chunk. With 512 queued frames, a first write of 64 frames delivers only 320 frames. It also retries terminal device errors because it ignores the result of snd_pcm_recover.

Keep an offset into the pending chunk until ALSA accepts all frames. Use nonblocking writes and bounded waits. Handle suspend recovery with separate resume and prepare calls so Audio.close can stop and join the pump. A zero write, failed recovery, or one second without progress stops the pump and stores its error. The next Audio.write or Audio.close joins the pump, releases the device, prints the stored error, and exits with status 1. The existing Audio effect types stay the same. The one-second timeout is the error policy selected for this patch.

Add a native Bend regression with ALSA's null output and controlled device return values. Positive writes reach the real ALSA library. The test checks all 255 first short-write lengths and 16 other cases. It verifies frame order, stereo channels, repeated partial writes, recovery, terminal errors, retry limits, and shutdown. Document the error policy in guide/EFFECTS.md.

Validation:

  • The real CLI builds and runs the native regression at -O3. All 271 cases pass. The default run takes 3.30 seconds.
  • The complete generated program passes AddressSanitizer, UndefinedBehaviorSanitizer, and ThreadSanitizer at -O0. No sanitizer checks are disabled. AddressSanitizer leak detection is enabled.
  • Ring controls pass at -O1 with the three sanitizers. They cover full-ring drops, wraparound, empty-ring silence, and 50 concurrent pump lifecycles.
  • Existing audio_only_open, audio_only_write, and audio_only_close tests pass in source and native lanes on Linux and macOS. The new test also passes source, JavaScript, and macOS native checks. JavaScript and macOS skip the Linux cases.
  • The repository gate passes 54/54. git diff --check passes.

Linux validation uses Debian 13 on aarch64, Clang 19.1.7, Bun 1.3.14, and ALSA 1.2.14. No physical ALSA device was tested. The cluster, performance, proof, and release gates were not run. Full sanitizer instrumentation at an optimized setting fails in the generated evaluator before the audio tests. The unchanged upstream program has the same pointer-offset diagnostic. The full sanitizer results above use the runtime's supported -O0 configuration.

The ALSA documentation describes partial blocking writes and the return values from recovery: ALSA PCM API.

@sebastian-griego
sebastian-griego marked this pull request as ready for review October 11, 2026 21:55
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