mirror of
https://github.com/Ryujinx/SDL.git
synced 2024-12-23 06:15:35 +00:00
audio: Tighten up possession of detectionLock during device open.
We don't need it for most of the time, and holding it during the backend's OpenDevice upsets ThreadSanitizer vs our PulseAudio code. Fixes #7427.
This commit is contained in:
parent
e51760e111
commit
c331b64d79
|
@ -1292,25 +1292,10 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_LockMutex(current_audio.detectionLock);
|
|
||||||
/* Find an available device ID... */
|
|
||||||
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
|
||||||
if (open_devices[id] == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id == SDL_arraysize(open_devices)) {
|
|
||||||
SDL_SetError("Too many open audio devices");
|
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!obtained) {
|
if (!obtained) {
|
||||||
obtained = &_obtained;
|
obtained = &_obtained;
|
||||||
}
|
}
|
||||||
if (!prepare_audiospec(desired, obtained)) {
|
if (!prepare_audiospec(desired, obtained)) {
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,11 +1317,11 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
|
if ((iscapture) && (current_audio.impl.OnlyHasDefaultCaptureDevice)) {
|
||||||
if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
|
if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
|
||||||
SDL_SetError("No such device");
|
SDL_SetError("No such device");
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
devname = NULL;
|
devname = NULL;
|
||||||
|
|
||||||
|
SDL_LockMutex(current_audio.detectionLock);
|
||||||
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
||||||
if ((open_devices[i]) && (open_devices[i]->iscapture)) {
|
if ((open_devices[i]) && (open_devices[i]->iscapture)) {
|
||||||
SDL_SetError("Audio device already open");
|
SDL_SetError("Audio device already open");
|
||||||
|
@ -1344,14 +1329,15 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
} else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
} else if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
|
||||||
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
|
if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
SDL_SetError("No such device");
|
SDL_SetError("No such device");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
devname = NULL;
|
devname = NULL;
|
||||||
|
|
||||||
|
SDL_LockMutex(current_audio.detectionLock);
|
||||||
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
for (i = 0; i < SDL_arraysize(open_devices); i++) {
|
||||||
if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
|
if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
|
@ -1359,6 +1345,7 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
} else if (devname != NULL) {
|
} else if (devname != NULL) {
|
||||||
/* if the app specifies an exact string, we can pass the backend
|
/* if the app specifies an exact string, we can pass the backend
|
||||||
an actual device handle thingey, which saves them the effort of
|
an actual device handle thingey, which saves them the effort of
|
||||||
|
@ -1367,19 +1354,20 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
It might still need to open a device based on the string for,
|
It might still need to open a device based on the string for,
|
||||||
say, a network audio server, but this optimizes some cases. */
|
say, a network audio server, but this optimizes some cases. */
|
||||||
SDL_AudioDeviceItem *item;
|
SDL_AudioDeviceItem *item;
|
||||||
|
SDL_LockMutex(current_audio.detectionLock);
|
||||||
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
|
for (item = iscapture ? current_audio.inputDevices : current_audio.outputDevices; item; item = item->next) {
|
||||||
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
|
if ((item->handle != NULL) && (SDL_strcmp(item->name, devname) == 0)) {
|
||||||
handle = item->handle;
|
handle = item->handle;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
|
if (!current_audio.impl.AllowsArbitraryDeviceNames) {
|
||||||
/* has to be in our device list, or the default device. */
|
/* has to be in our device list, or the default device. */
|
||||||
if ((handle == NULL) && (devname != NULL)) {
|
if ((handle == NULL) && (devname != NULL)) {
|
||||||
SDL_SetError("No such device.");
|
SDL_SetError("No such device.");
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1387,10 +1375,8 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice));
|
device = (SDL_AudioDevice *)SDL_calloc(1, sizeof(SDL_AudioDevice));
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
device->id = id + 1;
|
|
||||||
device->spec = *obtained;
|
device->spec = *obtained;
|
||||||
device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
|
||||||
device->handle = handle;
|
device->handle = handle;
|
||||||
|
@ -1404,7 +1390,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
device->mixer_lock = SDL_CreateMutex();
|
device->mixer_lock = SDL_CreateMutex();
|
||||||
if (device->mixer_lock == NULL) {
|
if (device->mixer_lock == NULL) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
SDL_SetError("Couldn't create mixer lock");
|
SDL_SetError("Couldn't create mixer lock");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1419,7 +1404,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
|
|
||||||
if (current_audio.impl.OpenDevice(device, devname) < 0) {
|
if (current_audio.impl.OpenDevice(device, devname) < 0) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1475,7 +1459,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
|
|
||||||
if (!device->stream) {
|
if (!device->stream) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1485,7 +1468,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2);
|
device->buffer_queue = SDL_NewDataQueue(SDL_AUDIOBUFFERQUEUE_PACKETLEN, obtained->size * 2);
|
||||||
if (!device->buffer_queue) {
|
if (!device->buffer_queue) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
SDL_SetError("Couldn't create audio buffer queue");
|
SDL_SetError("Couldn't create audio buffer queue");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1503,12 +1485,28 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len);
|
device->work_buffer = (Uint8 *)SDL_malloc(device->work_buffer_len);
|
||||||
if (device->work_buffer == NULL) {
|
if (device->work_buffer == NULL) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
SDL_OutOfMemory();
|
SDL_OutOfMemory();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Find an available device ID... */
|
||||||
|
SDL_LockMutex(current_audio.detectionLock);
|
||||||
|
for (id = min_id - 1; id < SDL_arraysize(open_devices); id++) {
|
||||||
|
if (open_devices[id] == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (id == SDL_arraysize(open_devices)) {
|
||||||
|
close_audio_device(device);
|
||||||
|
SDL_SetError("Too many open audio devices");
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
device->id = id + 1;
|
||||||
open_devices[id] = device; /* add it to our list of open devices. */
|
open_devices[id] = device; /* add it to our list of open devices. */
|
||||||
|
SDL_UnlockMutex(current_audio.detectionLock);
|
||||||
|
|
||||||
/* Start the audio thread if necessary */
|
/* Start the audio thread if necessary */
|
||||||
if (!current_audio.impl.ProvidesOwnCallbackThread) {
|
if (!current_audio.impl.ProvidesOwnCallbackThread) {
|
||||||
|
@ -1521,7 +1519,6 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
if (!startup_data.startup_semaphore) {
|
if (!startup_data.startup_semaphore) {
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_SetError("Couldn't create audio thread startup semaphore");
|
SDL_SetError("Couldn't create audio thread startup semaphore");
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1532,14 +1529,12 @@ static SDL_AudioDeviceID open_audio_device(const char *devname, int iscapture,
|
||||||
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
||||||
close_audio_device(device);
|
close_audio_device(device);
|
||||||
SDL_SetError("Couldn't create audio thread");
|
SDL_SetError("Couldn't create audio thread");
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SemWait(startup_data.startup_semaphore);
|
SDL_SemWait(startup_data.startup_semaphore);
|
||||||
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
SDL_DestroySemaphore(startup_data.startup_semaphore);
|
||||||
}
|
}
|
||||||
SDL_UnlockMutex(current_audio.detectionLock);
|
|
||||||
|
|
||||||
return device->id;
|
return device->id;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue