mirror of
https://github.com/mpv-player/mpv
synced 2025-02-22 07:46:55 +00:00
If the audio callback suddenly stops, and the AO provides no "reset" callback, then reset() could deadlock by waiting on the audio callback forever. The waiting was needed to enter a consistent state, where the audio callback guarantees it won't access the ringbuffer. This in turn is needed because mp_ring_reset() is not concurrency-safe. This active waiting is unavoidable. But the way it was implemented, the audio callback had to call ao_read_data() at least once when reset() is called. Fix this by making ao_read_data() set a flag upon entering and leaving, which basically turns p->state into some sort of spinlock. The audio callback actually never needs to spin, because there are only 2 states: playing audio, or playing silence. This might be a bit surprising, because usually atomic_compare_exchange_strong() requires a retry-loop idiom for correct operation. This commit is needed because ao_wasapi can (or will in the future) randomly stop the audio callback in certain corner cases. Then the player would hang forever in reset(). |
||
---|---|---|
.. | ||
ao_alsa.c | ||
ao_coreaudio_exclusive.c | ||
ao_coreaudio_properties.c | ||
ao_coreaudio_properties.h | ||
ao_coreaudio_utils.c | ||
ao_coreaudio_utils.h | ||
ao_coreaudio.c | ||
ao_dsound.c | ||
ao_jack.c | ||
ao_lavc.c | ||
ao_null.c | ||
ao_openal.c | ||
ao_oss.c | ||
ao_pcm.c | ||
ao_portaudio.c | ||
ao_pulse.c | ||
ao_rsound.c | ||
ao_sdl.c | ||
ao_sndio.c | ||
ao_wasapi_utils.c | ||
ao_wasapi_utils.h | ||
ao_wasapi.c | ||
ao_wasapi.h | ||
ao.c | ||
ao.h | ||
internal.h | ||
pull.c | ||
push.c |