8a: assert_no_alloc on audio-thread callbacks

Wraps the three audio-thread `process` callbacks
(`capture_process`, `playback_process`, `tap_process`) with
`assert_no_alloc::assert_no_alloc(|| inner(...))`. The
`headroom-cli` binary installs `AllocDisabler` as `#[global_allocator]`
so any allocation inside one of those blocks during debug builds
aborts the process with "memory allocation of N bytes failed".

Each callback was renamed to `*_inner` to keep the thin wrapper
function pointer stable for pipewire-rs's `process(fn_ptr)`.

`assert_no_alloc`'s `disable_release` is on by default — release
builds get the system allocator unwrapped and the macros become
no-ops, so the audio thread pays zero runtime cost in production.

Verified

  Positive smoke (5 s of 1 kHz sine through processed): daemon
  stays up across thousands of capture/playback/tap callbacks. No
  abort. Audio threads are alloc-free as designed.

  Negative smoke (temporarily inserted `Vec::with_capacity(1024)`
  inside `capture_process_inner`): daemon aborts (SIGABRT, exit
  134) on the first audio callback with the expected
  "memory allocation of 1024 bytes failed" stderr message —
  confirming the harness is wired correctly and not silently a
  no-op. Sanity-check alloc reverted before commit.

  185 tests pass; clippy clean at -D warnings --all-targets.
This commit is contained in:
atagen 2026-05-21 16:21:53 +10:00
parent 8af6dff98d
commit 9220143db7
6 changed files with 43 additions and 2 deletions

View file

@ -18,6 +18,7 @@ headroom-client = { workspace = true }
headroom-core = { workspace = true }
headroom-ipc = { workspace = true }
assert_no_alloc = { workspace = true }
clap = { workspace = true }
crossbeam-channel = { workspace = true }
crossterm = { workspace = true }