Skip to content

Expose device audio I/O workgroup via capi - #280

Open
kinetiknz wants to merge 3 commits into
trailblazerfrom
workgroup
Open

kinetiknz wants to merge 3 commits into
trailblazerfrom
workgroup

Conversation

@kinetiknz

Copy link
Copy Markdown
Contributor

Query kAudioDevicePropertyIOThreadOSWorkgroup for each stream's output and input device during setup() and cache the result in CoreStreamData. Add a C-ABI entry point, audiounit_stream_get_workgroup, returning a retained os_workgroup_t so auxiliary threads that cooperate on a stream's audio deadline (e.g. audioipc's cross-process callback dispatch thread) can join the workgroup.

Introduces a small RAII WorkGroup wrapper over os_workgroup_t to manage the +1 retain transferred from CoreAudio and from the capi. Query failures are non-fatal: older OS versions and some virtual devices do not publish a workgroup.

Query kAudioDevicePropertyIOThreadOSWorkgroup for each stream's output
and input device during setup() and cache the result in CoreStreamData.
Add a C-ABI entry point, audiounit_stream_get_workgroup, returning a
retained os_workgroup_t so auxiliary threads that cooperate on a
stream's audio deadline (e.g. audioipc's cross-process callback dispatch
thread) can join the workgroup.

Introduces a small RAII WorkGroup wrapper over os_workgroup_t to manage
the +1 retain transferred from CoreAudio and from the capi.  Query
failures are non-fatal: older OS versions and some virtual devices do
not publish a workgroup.
@kinetiknz
kinetiknz requested a review from ChunMinChang April 23, 2026 04:04
@kinetiknz kinetiknz self-assigned this Apr 23, 2026

@ChunMinChang ChunMinChang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Comment thread src/backend/tests/interfaces.rs Outdated
// Querying a second time should return a fresh retained reference,
// not the same pointer invalidated. Both must be released.
let wg2 = unsafe { crate::capi::audiounit_stream_get_workgroup(stream) };
assert!(!wg2.is_null());

@ChunMinChang ChunMinChang Apr 24, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should assert_eq!(wq, wq2) be added here?
I am a bit confused about why we need two calls here without checking the two handle are same or not. os_release returns void, so nothing can be checked. Since internal ref-count for the Property::IOThreadOSWorkgroup handle is not detectable I guess, the ref-count imbalance can only be caught under ASAN build.

@kinetiknz kinetiknz Oct 1, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added assert_eq!(wg, wg2) and clarified the comment: both calls return the same cached workgroup pointer, with a separate retained reference that must be released for each call. The equality check verifies identity; it does not itself prove refcount balance, so sanitizer coverage remains useful.

I also merged current trailblazer and resolved the import conflict with the ringbuf update, preserving the new ringbuf imports and the WorkGroup import. Formatting, Clippy, and both focused workgroup tests pass locally with access to the real output device; the positive workgroup case ran rather than taking the no-device/no-workgroup skip path.

Thanks for the reviews. Once CI is green on the updated branch, is there anything else needed before merging?

CI update: the macOS 14/15 stable jobs and AddressSanitizer passed on the updated branch (both push and PR runs). ThreadSanitizer failed in the existing ringbuf consumer-cache path during device-unplug tests: input/output callbacks reach BufferManager::available_frames / consumer operations and race on the cached index. The current upstream commit 4b6a206 has the same report in its September 22 nightly run. This remains a real unresolved sanitizer report; the workflow marks the nightly job experimental (continue-on-error).

Current PR job: https://github.com/mozilla/cubeb-coreaudio-rs/actions/runs/36868009366/job/110388304641
Upstream baseline: https://github.com/mozilla/cubeb-coreaudio-rs/actions/runs/35798561451/job/106983421589

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.

3 participants