PulseAudio: fix scan devices out of memory race condition

This commit is contained in:
Andrew Kelley 2015-08-26 15:54:03 -07:00
parent f7b37ef527
commit 8d3a32e668
3 changed files with 25 additions and 26 deletions

View file

@ -272,17 +272,11 @@ Then look at `html/index.html` in a browser.
## Roadmap ## Roadmap
0. Make sure PulseAudio can handle refresh devices crashing before 0. Detect PulseAudio server going offline and emit `on_backend_disconnect`.
block_until_have_devices 0. Ability to "activate" a buffer-flexible outstream by jumping the gun and
0. Integrate into libgroove and test with Groove Basin causing `write_callback` to be called early.
0. clear buffer maybe could take an argument to say how many frames to not clear - Use the same mechanism when destroying the outstream
0. Verify that JACK xrun callback context is the same as process callback. 0. Create a test for input stream overflow handling.
If not, might need to hav xrun callback set a flag and have process callback
call the underflow callback.
0. Create a test for pausing and resuming input and output streams.
- Should pause/resume be callable from outside the callbacks?
- Ensure double pausing / double resuming works fine.
- test clearing the buffer
0. Create a test for the latency / synchronization API. 0. Create a test for the latency / synchronization API.
- Input is an audio file and some events indexed at particular frame - when - Input is an audio file and some events indexed at particular frame - when
listening the events should line up exactly with a beat or visual listening the events should line up exactly with a beat or visual
@ -290,18 +284,12 @@ Then look at `html/index.html` in a browser.
- Play the audio file, have the user press an input right at the beat. Find - Play the audio file, have the user press an input right at the beat. Find
out what the frame index it thinks the user pressed it at and make sure out what the frame index it thinks the user pressed it at and make sure
that is correct. that is correct.
0. Create a test for input stream overflow handling. 0. Create a test for pausing and resuming input and output streams.
0. Allow calling functions from outside the callbacks as long as they first - Should pause/resume be callable from outside the callbacks?
call lock and then unlock when done. - Ensure double pausing / double resuming works fine.
0. write detailed docs on buffer underflows explaining when they occur, what state - test clearing the buffer
changes are related to them, and how to recover from them.
0. Detect PulseAudio server going offline and emit `on_backend_disconnect`.
0. Support for stream icon.
- PulseAudio: XDG icon name
- WASAPI: path to .exe, .dll, or .ico
- CoreAudio: CFURLRef image file
## Planned Uses for libsoundio ## Projects Using libsoundio
* [Genesis](https://github.com/andrewrk/genesis) * [Genesis](https://github.com/andrewrk/genesis)
* [libgroove](https://github.com/andrewrk/libgroove) ([Groove Basin](https://github.com/andrewrk/groovebasin)) * [Groove Basin](https://github.com/andrewrk/groovebasin) (via [libgroove](https://github.com/andrewrk/libgroove))

View file

@ -322,7 +322,16 @@ struct SoundIo {
/// SoundIoErrorBackendDisconnected. This callback is only called during a /// SoundIoErrorBackendDisconnected. This callback is only called during a
/// call to ::soundio_flush_events or ::soundio_wait_events. /// call to ::soundio_flush_events or ::soundio_wait_events.
/// If you do not supply a callback, the default will crash your program /// If you do not supply a callback, the default will crash your program
/// with an error message. /// with an error message. This callback is also called when the thread
/// that retrieves device information runs into an unrecoverable condition
/// such as running out of memory.
///
/// Possible errors:
/// * #SoundIoErrorBackendDisconnected
/// * #SoundIoErrorNoMem
/// * #SoundIoErrorSystemResources
/// * #SoundIoErrorOpeningDevice - unexpected problem accessing device
/// information
void (*on_backend_disconnect)(struct SoundIo *, int err); void (*on_backend_disconnect)(struct SoundIo *, int err);
/// Optional callback. Called from an unknown thread that you should not use /// Optional callback. Called from an unknown thread that you should not use
/// to call any soundio functions. You may use this to signal a condition /// to call any soundio functions. You may use this to signal a condition

View file

@ -223,7 +223,9 @@ static void finish_device_query(SoundIoPrivate *si) {
} }
if (sipa->device_query_err) { if (sipa->device_query_err) {
sipa->device_scan_queued.store(true); pa_threaded_mainloop_signal(sipa->main_loop, 0);
soundio->on_events_signal(soundio);
soundio->on_backend_disconnect(soundio, sipa->device_query_err);
return; return;
} }
@ -463,7 +465,7 @@ static void block_until_have_devices(SoundIoPrivate *si) {
if (sipa->have_devices_flag) if (sipa->have_devices_flag)
return; return;
pa_threaded_mainloop_lock(sipa->main_loop); pa_threaded_mainloop_lock(sipa->main_loop);
while (!sipa->have_devices_flag) { while (!sipa->have_devices_flag && !sipa->device_query_err) {
pa_threaded_mainloop_wait(sipa->main_loop); pa_threaded_mainloop_wait(sipa->main_loop);
} }
pa_threaded_mainloop_unlock(sipa->main_loop); pa_threaded_mainloop_unlock(sipa->main_loop);