audio: Backed out the audio-thread detaching changes.
It added a ton of complexity. A simpler solution might arise at some
point though.
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index 08b801e..460852d 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -708,38 +708,6 @@
free_audio_queue(packet);
}
-void
-SDL_FinalizeAudioDevice(SDL_AudioDevice *device)
-{
- if (!device) {
- return;
- }
-
- SDL_AtomicSet(&device->shutdown, 1); /* just in case. */
- SDL_AtomicSet(&device->enabled, 0);
-
- /* lock/unlock here so we don't race if the audio thread saw the shutdown
- var without locking, and the thread that requested shutdown is now
- trying to unlock the mutex while we destroy it. Threading is hard. */
- current_audio.impl.LockDevice(device);
- current_audio.impl.UnlockDevice(device);
-
- if (device->mixer_lock != NULL) {
- SDL_DestroyMutex(device->mixer_lock);
- }
- SDL_free(device->fake_stream);
- if (device->convert.needed) {
- SDL_free(device->convert.buf);
- }
- if (device->hidden != NULL) {
- current_audio.impl.CloseDevice(device);
- }
-
- free_audio_queue(device->buffer_queue_head);
- free_audio_queue(device->buffer_queue_pool);
-
- SDL_free(device);
-}
/* The general mixing thread function */
static int SDLCALL
@@ -819,8 +787,6 @@
/* Wait for the audio to drain. */
SDL_Delay(((device->spec.samples * 1000) / device->spec.freq) * 2);
- SDL_FinalizeAudioDevice(device);
-
return 0;
}
@@ -902,8 +868,6 @@
current_audio.impl.FlushCapture(device);
- SDL_FinalizeAudioDevice(device);
-
return 0;
}
@@ -1118,19 +1082,6 @@
return;
}
- /* It's possible the audio device can hang at the OS level for
- several reasons (buggy drivers, etc), so if we've got a thread in
- flight, we mark the device as ready to shutdown and return
- immediately. The thread will either notice this and clean everything
- up when it can, or it's frozen and helpless, but since we've already
- detached the thread, it's none of our concern. Otherwise, we might
- hang too. */
-
- /* Note this can still hang if we initialized the device but failed
- to finish setting up, forcing _this_ thread to do the cleanup, but
- oh well. */
-
- /* take it out of our open list now, though, even if device hangs. */
if (device->id > 0) {
SDL_AudioDevice *opendev = open_devices[device->id - 1];
SDL_assert((opendev == device) || (opendev == NULL));
@@ -1139,43 +1090,26 @@
}
}
- if (!current_audio.impl.ProvidesOwnCallbackThread && !device->thread) {
- /* no thread...maybe we're cleaning up a half-opened failure. */
- SDL_FinalizeAudioDevice(device); /* do it ourselves. */
- } else if (current_audio.impl.ProvidesOwnCallbackThread) {
- /* !!! FIXME: this is sort of a mess, because we _should_ treat this
- !!! FIXME: the same as our internal threads, but those targets
- !!! FIXME: need refactoring first: they need to call
- !!! FIXME: SDL_FinalizeAudioDevice() themselves and also have
- !!! FIXME: their CloseDevice() code deal with cleaning up
- !!! FIXME: half-initialized opens _and_ normal runs. So for now,
- !!! FIXME: nothing to do here but pray this doesn't hang.
- !!! FIXME: (the TODO list: coreaudio, emscripten, nacl, haiku) */
- SDL_FinalizeAudioDevice(device);
- } else {
- Uint32 delay = 0;
-
- if (!device->iscapture) {
- const SDL_AudioSpec *spec = &device->spec;
- delay = ((spec->samples * 1000) / spec->freq) * 2;
- }
-
- /* Lock to make sure an audio callback doesn't fire after we return.
- Presumably, if a device hangs, it'll not be holding this mutex,
- since it should only be held during the app's audio callback. */
- current_audio.impl.LockDevice(device);
- SDL_AtomicSet(&device->shutdown, 1); /* let the thread do it. */
- SDL_AtomicSet(&device->enabled, 0);
- current_audio.impl.UnlockDevice(device);
-
- /* device is no longer safe to touch at this point. */
-
- if (delay > 0) {
- /* Block the amount that is roughly pending for playback, so we
- don't drop audio if the process exits right after this call. */
- SDL_Delay(delay);
- }
+ SDL_AtomicSet(&device->shutdown, 1);
+ SDL_AtomicSet(&device->enabled, 0);
+ if (device->thread != NULL) {
+ SDL_WaitThread(device->thread, NULL);
}
+ if (device->mixer_lock != NULL) {
+ SDL_DestroyMutex(device->mixer_lock);
+ }
+ SDL_free(device->fake_stream);
+ if (device->convert.needed) {
+ SDL_free(device->convert.buf);
+ }
+ if (device->hidden != NULL) {
+ current_audio.impl.CloseDevice(device);
+ }
+
+ free_audio_queue(device->buffer_queue_head);
+ free_audio_queue(device->buffer_queue_pool);
+
+ SDL_free(device);
}
@@ -1494,9 +1428,6 @@
SDL_SetError("Couldn't create audio thread");
return 0;
}
-
- /* don't ever join on this thread; it will clean itself up. */
- SDL_DetachThread(device->thread);
}
return device->id;