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.
This commit is contained in:
Ryan C. Gordon
2025-04-24 22:17:13 -04:00
parent da3c864d4c
commit b28449a58c

View File

@@ -1502,31 +1502,24 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid) const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
{ {
bool isstack = false;
char *string = NULL;
const char *result = NULL; const char *result = NULL;
SDL_AudioDevice *device = NULL; SDL_AudioDevice *device = NULL;
// This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so if (!SDL_GetCurrentAudioDriver()) {
// it doesn't have to lock the whole device. However, just to make sure the device pointer itself SDL_SetError("Audio subsystem is not initialized");
// remains valid (in case the device is unplugged at the wrong moment), we hold the } else {
// device_hash_lock while we copy the string. // This does not call ObtainPhysicalAudioDevice() because the device's name never changes, so
SDL_LockRWLockForReading(current_audio.device_hash_lock); // it doesn't have to lock the whole device. However, just to make sure the device pointer itself
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device); // remains valid (in case the device is unplugged at the wrong moment), we hold the
if (device) { // device_hash_lock while we copy the string.
const size_t slen = SDL_strlen(device->name) + 1; SDL_LockRWLockForReading(current_audio.device_hash_lock);
// 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. SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
// So just try to tuck this into a little stack space while we're holding device_hash_lock. if (!device) {
string = SDL_small_alloc(char, slen, &isstack); SDL_SetError("Invalid audio device instance ID");
if (string) { } else {
SDL_strlcpy(string, device->name, slen); result = SDL_GetPersistentString(device->name);
} }
} SDL_UnlockRWLock(current_audio.device_hash_lock);
SDL_UnlockRWLock(current_audio.device_hash_lock);
if (string) {
result = SDL_GetPersistentString(string);
SDL_small_free(string, isstack);
} }
return result; return result;