changeset 2004:66f08024d9e9

Fix occasional deadlock on startup when using audio sync
author Michael Pavone <pavone@retrodev.com>
date Sun, 11 Oct 2020 18:01:48 -0700
parents 4c418ee9a9d8
children 3ce38692a3f2
files render_sdl.c
diffstat 1 files changed, 14 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/render_sdl.c	Sun Jul 19 18:10:40 2020 -0700
+++ b/render_sdl.c	Sun Oct 11 18:01:48 2020 -0700
@@ -172,7 +172,13 @@
 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_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);