Codex flagged a real-but-rare race in `try_bind_default_metadata`:
the daemon installs the metadata listener then immediately writes
`default.audio.sink = headroom-processed`, relying on PipeWire to
deliver the prior value to the listener before our write. In
practice this works (pw-metadata replays current state to a
freshly-installed listener), but two failure modes leak through:
1. **Prior daemon left the world dirty.** If a previous daemon
run set default to `headroom-processed` and didn't restore
before exiting, the listener replays "headroom-processed" —
`on_metadata_property` recognises that as our own promotion
and returns early. `real_sink.name` is never captured.
Bypass routes log "no real sink known" forever.
2. **No replay event.** If the listener doesn't fire for any
reason — broken PipeWire, an event-bus hiccup,
pipewire-rs's `add_listener_local` racing with our write —
same outcome.
Fix: instead of trying to win the listener race
(pipewire-rs has no synchronous metadata getter, and `Core::sync`
needs an async done-callback we don't have plumbing for), make
`try_capture_real_sink` self-heal. When `real_sink.name` is still
`None` and we see *any* non-processed `Audio/Sink` on the registry,
adopt it as the fallback real sink. A subsequent
`default.audio.sink` event will refine the choice via the existing
`adopt_new_real_sink` path if WP picks something else.
This is a belt-and-braces patch — the listener path stays the
primary mechanism, the fallback only kicks in when that path
hasn't produced a name. In steady-state (the common case where
listener replay works) it changes nothing.
Verified
Cold start with PipeWire's `default.audio.sink` set to the
Mbox: daemon logs `preferred_real_sink updated sink=Mbox`
via the listener path; the fallback's
`adopting first available Audio/Sink as fallback` log does
not fire. No regression for the steady state.
188 tests pass; clippy clean at -D warnings --all-targets.
|
||
|---|---|---|
| .. | ||
| headroom-cli | ||
| headroom-client | ||
| headroom-core | ||
| headroom-dsp | ||
| headroom-ipc | ||