summaryrefslogtreecommitdiffstats
path: root/player/command.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-11-09 15:22:00 +0100
committerwm4 <wm4@nowhere>2014-11-09 15:23:40 +0100
commite4403523131a69a92a8418bb3714090a408680c7 (patch)
treef57c7161e06ecdff1f16e788242c42506eaae79e /player/command.c
parent0025f0042f68b664ab9e62ebd0279e0485f3eaa8 (diff)
downloadmpv-e4403523131a69a92a8418bb3714090a408680c7.tar.bz2
mpv-e4403523131a69a92a8418bb3714090a408680c7.tar.xz
audio/out/pull: avoid deadlock if audio callback stops
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().
Diffstat (limited to 'player/command.c')
0 files changed, 0 insertions, 0 deletions