Selaa lähdekoodia

audio: SDL_GetAudioDeviceName() doesn't need a full device lock.

Fixes https://github.com/libsdl-org/sdl2-compat/issues/468

(cherry picked from commit e8bd9cc150b7e54c24e005327511976cb102d005)
Ryan C. Gordon 4 kuukautta sitten
vanhempi
commit
982b778e45
1 muutettua tiedostoa jossa 23 lisäystä ja 3 poistoa
  1. 23 3
      src/audio/SDL_audio.c

+ 23 - 3
src/audio/SDL_audio.c

@@ -1502,12 +1502,32 @@ SDL_AudioDevice *SDL_FindPhysicalAudioDeviceByHandle(void *handle)
 
 const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
 {
+    bool isstack;
+    char *string = NULL;
     const char *result = NULL;
-    SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
+    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) {
-        result = SDL_GetPersistentString(device->name);
+        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);
+        }
+    }
+    SDL_UnlockRWLock(current_audio.device_hash_lock);
+
+    if (string) {
+        result = SDL_GetPersistentString(string);
+        SDL_small_free(string, isstack);
     }
-    ReleaseAudioDevice(device);
 
     return result;
 }