From 2ecfb587c3ebb613ba8743857caa60ffe4b261fa Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 11 Oct 2020 18:01:48 -0700 Subject: Fix occasional deadlock on startup when using audio sync --- render_sdl.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'render_sdl.c') diff --git a/render_sdl.c b/render_sdl.c index 9e2c9ae..81c2675 100755 --- a/render_sdl.c +++ b/render_sdl.c @@ -172,7 +172,13 @@ void render_free_audio_opaque(void *opaque) void render_audio_created(audio_source *source) { if (sync_src == SYNC_AUDIO) { - SDL_PauseAudio(0); + //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs + //since our callback can itself be stuck waiting on the audio_ready condition variable + //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock + //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here + if (SDL_GetAudioStatus() == SDL_AUDIO_PAUSED) { + SDL_PauseAudio(0); + } } if (current_system && sync_src == SYNC_AUDIO_THREAD) { system_request_exit(current_system, 0); @@ -195,7 +201,13 @@ void render_source_paused(audio_source *src, uint8_t remaining_sources) void render_source_resumed(audio_source *src) { if (sync_src == SYNC_AUDIO) { - SDL_PauseAudio(0); + //SDL_PauseAudio acquires the audio device lock, which is held while the callback runs + //since our callback can itself be stuck waiting on the audio_ready condition variable + //calling SDL_PauseAudio(0) again for audio sources after the first can deadlock + //fortunately SDL_GetAudioStatus does not acquire the lock so is safe to call here + if (SDL_GetAudioStatus() == SDL_AUDIO_PAUSED) { + SDL_PauseAudio(0); + } } if (current_system && sync_src == SYNC_AUDIO_THREAD) { system_request_exit(current_system, 0); -- cgit v1.2.3