Skip to content

Conversation

@roderickvd
Copy link
Member

This PR updates alsa-rs to 0.11 and fixes several related issues around device enumeration, duplex device queries, and ALSA's stderr spam during enumeration. This also includes some quality-of-life improvements like Debug derives and better error handling.

1. Reverts device handle caching

Previously, we cached device handles to avoid opening them repeatedly (#506). This seemed efficient, and fixed drivers that have issues with rapidly closing and opening, but it caused two real problems:

  • When you tried to query both input and output configs on a duplex device, the second query would fail with EBUSY because we already had it open
  • Other applications couldn't access devices while we were enumerating them

I've reverted the caching: devices are now opened fresh for each operation. For broken drivers where rapid open/close causes issues (like some NVIDIA HDMI cards), applications can use the new DeviceBusy error variant to implement retry logic.

Fixes:

2. Suppresses ALSA's stderr spam

ALSA has the habit of printing error messages directly to stderr during normal device enumeration. Users were understandably confused by this. The enumerate.rs example now shows how to use the new alsa::Output::local_error_handler() to suppress these messages during enumeration.

Fixes:

3. Manages ALSA's global configuration

ALSA maintains a process-global configuration cache that we were never properly initializing or cleaning up. This led to memory leaks that showed up in Valgrind - somewhat false positives, but still.

Now we call alsa::config::update() when creating the first Host, and alsa::config::update_free_global() when dropping the last one, after the last Device and Stream are dropped as well. The former reduces Valgrind reports, the latter correctly throws an error when ALSA is configured incorrectly.

4. Handling of retriable errors with DeviceBusy

I've added a new DeviceBusy error variant to several error types. This lets applications distinguish between retriable errors (like EBUSY or EAGAIN) and permanent failures (like ENOENT or EPERM). This allows users to implement smart retry logic when it makes sense, and counter the rapid open/close issues described above.

5. Debug implementations

I've added Debug derives to Host, Device, Stream, and internal types.

6. Breaking changes

The new DeviceBusy error variant is technically breaking because the error enums weren't marked as #[non_exhaustive]. Users with match statements that don't have a catch-all pattern will get compilation errors. This will require a semver minor update.

* add Debug derives
* improve error handling
Remove handle caching introduced in #506. The caching held devices open
during enumeration, which prevented querying both input and output configs
on duplex devices (EBUSY errors) and blocked other applications from
accessing the devices.

For the rare hardware where rapid open/close is problematic (like some
NVIDIA HDMI cards), applications can now implement retry logic using the
new DeviceBusy error variant, which separates retriable errors (EBUSY,
EAGAIN) from permanent failures (ENOENT, EPERM, etc).

Fixes:
- #615
- #634
When the last Host is dropped, free the global ALSA config cache via
alsa::config::update_free_global. This reduces Valgrind errors.

This comment was marked as resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants