SDL: audio: Tweak SDL_GetAudioDeviceName.

From b28449a58cd4914c13023692b3650cd8e00cc5c2 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
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 78faf7fdacd7c..a3a115c48d6b2 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;