Skip to content

Commit

Permalink
audio: Backed out the audio-thread detaching changes.
Browse files Browse the repository at this point in the history
It added a ton of complexity. A simpler solution might arise at some
point though.
  • Loading branch information
icculus committed Oct 7, 2016
1 parent 24df68e commit 7d2108c
Showing 1 changed file with 18 additions and 87 deletions.
105 changes: 18 additions & 87 deletions src/audio/SDL_audio.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -902,8 +868,6 @@ SDL_CaptureAudio(void *devicep)

current_audio.impl.FlushCapture(device);

SDL_FinalizeAudioDevice(device);

return 0;
}

Expand Down Expand Up @@ -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));
Expand All @@ -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);
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);
}

/* device is no longer safe to touch at this point. */
free_audio_queue(device->buffer_queue_head);
free_audio_queue(device->buffer_queue_pool);

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_free(device);
}


Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 7d2108c

Please sign in to comment.