mirror of https://github.com/encounter/SDL.git
audio: Backed out the audio-thread detaching changes.
It added a ton of complexity. A simpler solution might arise at some point though.
This commit is contained in:
parent
24df68ea33
commit
7d2108ce81
|
@ -708,38 +708,6 @@ SDL_ClearQueuedAudio(SDL_AudioDeviceID devid)
|
|||
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 @@ SDL_RunAudio(void *devicep)
|
|||
/* 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 @@ SDL_CaptureAudio(void *devicep)
|
|||
|
||||
current_audio.impl.FlushCapture(device);
|
||||
|
||||
SDL_FinalizeAudioDevice(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1118,19 +1082,6 @@ close_audio_device(SDL_AudioDevice * device)
|
|||
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 @@ close_audio_device(SDL_AudioDevice * device)
|
|||
}
|
||||
}
|
||||
|
||||
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 @@ open_audio_device(const char *devname, int iscapture,
|
|||
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;
|
||||
|
|
Loading…
Reference in New Issue