SDL: coreaudio: Dispose of AudioQueue before waiting on the thread. (266ca)

From 266ca2c933a308fe6ac21c29ce034637fb05e015 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Wed, 19 Oct 2022 09:14:16 -0400
Subject: [PATCH] coreaudio: Dispose of AudioQueue before waiting on the
 thread.

Otherwise the thread might block for a long time (more than 10 seconds!).
It's not clear to me why this happens, or why its safe to do this with a
resource that's still in use, but we have, until recently, always
disposed of the AudioQueue first, so changing back is probably okay.

Also changed the disposal to allow in-flight buffers to reach hardware;
otherwise you lose the last little bit of audio that's already been queued
but not played, which you can hear clearly in the loopwave test program.

Fixes #6377.
(cherry picked from commit e7ab581d796aa83f7d028ea4249fdc66600df173)
---
 src/audio/coreaudio/SDL_coreaudio.m | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/audio/coreaudio/SDL_coreaudio.m b/src/audio/coreaudio/SDL_coreaudio.m
index feca5b5aa0c8..43066f3ec682 100644
--- a/src/audio/coreaudio/SDL_coreaudio.m
+++ b/src/audio/coreaudio/SDL_coreaudio.m
@@ -704,6 +704,11 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
     /* if callback fires again, feed silence; don't call into the app. */
     SDL_AtomicSet(&this->paused, 1);
 
+    /* dispose of the audio queue before waiting on the thread, or it might stall for a long time! */
+    if (this->hidden->audioQueue) {
+        AudioQueueDispose(this->hidden->audioQueue, 0);
+    }
+
     if (this->hidden->thread) {
         SDL_assert(SDL_AtomicGet(&this->shutdown) != 0);  /* should have been set by SDL_audio.c */
         SDL_WaitThread(this->hidden->thread, NULL);
@@ -733,10 +738,6 @@ static BOOL update_audio_session(_THIS, SDL_bool open, SDL_bool allow_playandrec
         open_devices = NULL;
     }
 
-    if (this->hidden->audioQueue) {
-        AudioQueueDispose(this->hidden->audioQueue, 1);
-    }
-
     if (this->hidden->ready_semaphore) {
         SDL_DestroySemaphore(this->hidden->ready_semaphore);
     }