diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 1a864054c..b256c7b3e 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -31,6 +31,12 @@ #define _THIS SDL_AudioDevice *_this +typedef struct AudioThreadStartupData +{ + SDL_AudioDevice *device; + SDL_sem *startup_semaphore; +} AudioThreadStartupData; + static SDL_AudioDriver current_audio; static SDL_AudioDevice *open_devices[16]; @@ -663,9 +669,10 @@ extern void Android_JNI_AudioSetThreadPriority(int, int); #endif /* The general mixing thread function */ -static int SDLCALL SDL_RunAudio(void *devicep) +static int SDLCALL SDL_RunAudio(void *userdata) { - SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; + const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata; + SDL_AudioDevice *device = startup_data->device; void *udata = device->callbackspec.userdata; SDL_AudioCallback callback = device->callbackspec.callback; int data_len = 0; @@ -685,6 +692,9 @@ static int SDLCALL SDL_RunAudio(void *devicep) /* Perform any thread setup */ device->threadid = SDL_ThreadID(); + + SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */ + current_audio.impl.ThreadInit(device); /* Loop, filling the audio buffers */ @@ -761,9 +771,10 @@ static int SDLCALL SDL_RunAudio(void *devicep) /* !!! FIXME: this needs to deal with device spec changes. */ /* The general capture thread function */ -static int SDLCALL SDL_CaptureAudio(void *devicep) +static int SDLCALL SDL_CaptureAudio(void *userdata) { - SDL_AudioDevice *device = (SDL_AudioDevice *)devicep; + const AudioThreadStartupData *startup_data = (const AudioThreadStartupData *) userdata; + SDL_AudioDevice *device = startup_data->device; const int silence = (int)device->spec.silence; const Uint32 delay = ((device->spec.samples * 1000) / device->spec.freq); const int data_len = device->spec.size; @@ -785,6 +796,9 @@ static int SDLCALL SDL_CaptureAudio(void *devicep) /* Perform any thread setup */ device->threadid = SDL_ThreadID(); + + SDL_SemPost(startup_data->startup_semaphore); /* SDL_OpenAudioDevice may now continue. */ + current_audio.impl.ThreadInit(device); /* Loop, filling the audio buffers */ @@ -1500,16 +1514,30 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture, if (!current_audio.impl.ProvidesOwnCallbackThread) { /* Start the audio thread */ char threadname[64]; + AudioThreadStartupData startup_data; + + startup_data.device = device; + startup_data.startup_semaphore = SDL_CreateSemaphore(0); + if (!startup_data.startup_semaphore) { + close_audio_device(device); + SDL_SetError("Couldn't create audio thread startup semaphore"); + SDL_UnlockMutex(current_audio.detectionLock); + return 0; + } (void)SDL_snprintf(threadname, sizeof(threadname), "SDLAudio%c%" SDL_PRIu32, (iscapture) ? 'C' : 'P', device->id); - device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, 0, device); + device->thread = SDL_CreateThreadInternal(iscapture ? SDL_CaptureAudio : SDL_RunAudio, threadname, 0, &startup_data); if (device->thread == NULL) { + SDL_DestroySemaphore(startup_data.startup_semaphore); close_audio_device(device); SDL_SetError("Couldn't create audio thread"); SDL_UnlockMutex(current_audio.detectionLock); return 0; } + + SDL_SemWait(startup_data.startup_semaphore); + SDL_DestroySemaphore(startup_data.startup_semaphore); } SDL_UnlockMutex(current_audio.detectionLock);