From 9abc692156aa183b05f05e8395a44d0bd5f72b10 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sun, 22 Oct 2023 17:01:49 -0400
Subject: [PATCH] audio: Another attempt to deal with device destruction from
device thread.
This only happens when closing a device from an event watcher, when the
device reports failure from its own thread.
---
src/audio/SDL_audio.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index b96dae2d9c72..f2d28a298950 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -1321,9 +1321,14 @@ int SDL_GetAudioDeviceFormat(SDL_AudioDeviceID devid, SDL_AudioSpec *spec, int *
// this expects the device lock to be held. !!! FIXME: no it doesn't...?
static void ClosePhysicalAudioDevice(SDL_AudioDevice *device)
{
- SDL_AtomicSet(&device->shutdown, 1);
+ SDL_AtomicSet(&device->shutdown, 1); // alert device thread that it should terminate.
+
if (device->thread != NULL) {
- SDL_WaitThread(device->thread, NULL);
+ if (SDL_GetThreadID(device->thread) == SDL_ThreadID()) {
+ SDL_DetachThread(device->thread); // we _are_ the device thread, just drift off into the ether when finished, nothing is waiting for us.
+ } else {
+ SDL_WaitThread(device->thread, NULL); // we're not the device thread, wait for it to terminate.
+ }
device->thread = NULL;
}
@@ -1345,7 +1350,6 @@ static void ClosePhysicalAudioDevice(SDL_AudioDevice *device)
SDL_copyp(&device->spec, &device->default_spec);
device->sample_frames = 0;
device->silence_value = SDL_GetSilenceValueForFormat(device->spec.format);
- SDL_AtomicSet(&device->shutdown, 0); // ready to go again.
}
void SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
@@ -1442,6 +1446,8 @@ static int OpenPhysicalAudioDevice(SDL_AudioDevice *device, const SDL_AudioSpec
return 0; // Braaaaaaaaains.
}
+ SDL_AtomicSet(&device->shutdown, 0); // make sure we don't kill the new thread immediately.
+
// These start with the backend's implementation, but we might swap them out with zombie versions later.
device->WaitDevice = current_audio.impl.WaitDevice;
device->PlayDevice = current_audio.impl.PlayDevice;