diff options
author | wm4 <wm4@nowhere> | 2014-11-09 15:22:00 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-11-09 15:23:40 +0100 |
commit | e4403523131a69a92a8418bb3714090a408680c7 (patch) | |
tree | f57c7161e06ecdff1f16e788242c42506eaae79e /demux | |
parent | 0025f0042f68b664ab9e62ebd0279e0485f3eaa8 (diff) |
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 'demux')
0 files changed, 0 insertions, 0 deletions