From b28449a58cd4914c13023692b3650cd8e00cc5c2 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Thu, 24 Apr 2025 22:17:13 -0400 Subject: [PATCH] audio: Tweak SDL_GetAudioDeviceName. - Add checks that ObtainPhysicalAudioDevice() was previously doing (is subsystem initialized, is device valid). - Remove optimizations that copy string to stack to release device_hash_lock before SDL_GetPersistentString is called. Probably not necessary, and made the code more complex. --- src/audio/SDL_audio.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index 78faf7fdac..a3a115c48d 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -1502,31 +1502,24 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle) const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid) { - bool isstack = false; - char *string = NULL; const char *result = NULL; SDL_AudioDevice *device = NULL; - // This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so - // it doesn't have to lock the whole device. However, just to make sure the device pointer itself - // remains valid (in case the device is unplugged at the wrong moment), we hold the - // device_hash_lock while we copy the string. - SDL_LockRWLockForReading(current_audio.device_hash_lock); - SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device); - if (device) { - const size_t slen = SDL_strlen(device->name) + 1; - // SDL_GetPersistentString might _also_ makes a copy, but it might also create a TLS slot and a hashtable before doing a lookup, malloc+copy, and insert. - // So just try to tuck this into a little stack space while we're holding device_hash_lock. - string = SDL_small_alloc(char, slen, &isstack); - if (string) { - SDL_strlcpy(string, device->name, slen); + if (!SDL_GetCurrentAudioDriver()) { + SDL_SetError("Audio subsystem is not initialized"); + } else { + // This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so + // it doesn't have to lock the whole device. However, just to make sure the device pointer itself + // remains valid (in case the device is unplugged at the wrong moment), we hold the + // device_hash_lock while we copy the string. + SDL_LockRWLockForReading(current_audio.device_hash_lock); + SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device); + if (!device) { + SDL_SetError("Invalid audio device instance ID"); + } else { + result = SDL_GetPersistentString(device->name); } - } - SDL_UnlockRWLock(current_audio.device_hash_lock); - - if (string) { - result = SDL_GetPersistentString(string); - SDL_small_free(string, isstack); + SDL_UnlockRWLock(current_audio.device_hash_lock); } return result;