Quellcode durchsuchen

audio: Fix some logic errors in the new device hashtable code.

Fixes #8395.
Ryan C. Gordon vor 1 Jahr
Ursprung
Commit
b22ffb9797
1 geänderte Dateien mit 22 neuen und 12 gelöschten Zeilen
  1. 22 12
      src/audio/SDL_audio.c

+ 22 - 12
src/audio/SDL_audio.c

@@ -256,9 +256,12 @@ static SDL_AudioDeviceID AssignAudioDeviceInstanceId(SDL_bool iscapture, SDL_boo
 // this assumes you hold the _physical_ device lock for this logical device! This will not unlock the lock or close the physical device!
 static void DestroyLogicalAudioDevice(SDL_LogicalAudioDevice *logdev)
 {
-    SDL_LockRWLockForWriting(current_audio.device_hash_lock);
-    SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) logdev->instance_id);
-    SDL_UnlockRWLock(current_audio.device_hash_lock);
+    // Remove ourselves from the device_hash hashtable.
+    if (current_audio.device_hash) {  // will be NULL while shutting down.
+        SDL_LockRWLockForWriting(current_audio.device_hash_lock);
+        SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) logdev->instance_id);
+        SDL_UnlockRWLock(current_audio.device_hash_lock);
+    }
 
     // remove ourselves from the physical device's list of logical devices.
     if (logdev->next) {
@@ -773,9 +776,14 @@ void SDL_QuitAudio(void)
     const void *value;
     void *iter = NULL;
     while (SDL_IterateHashTable(device_hash, &key, &value, &iter)) {
-        SDL_AudioDevice *device = (SDL_AudioDevice *) value;
-        SDL_AtomicSet(&device->shutdown, 1);
-        DestroyPhysicalAudioDevice(device);
+        // bit #1 of devid is set for physical devices and unset for logical.
+        const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
+        const SDL_bool isphysical = (devid & (1<<1)) ? SDL_TRUE : SDL_FALSE;
+        if (isphysical) {
+            SDL_AudioDevice *device = (SDL_AudioDevice *) value;
+            SDL_AtomicSet(&device->shutdown, 1);
+            DestroyPhysicalAudioDevice(device);
+        }
     }
 
     // Free the driver data
@@ -1513,12 +1521,14 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
         }
         SDL_UnlockMutex(device->lock);
 
-        SDL_LockRWLockForWriting(current_audio.device_hash_lock);
-        const SDL_bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) retval, logdev);
-        SDL_UnlockRWLock(current_audio.device_hash_lock);
-        if (!inserted) {
-            SDL_CloseAudioDevice(retval);
-            retval = 0;
+        if (retval) {
+            SDL_LockRWLockForWriting(current_audio.device_hash_lock);
+            const SDL_bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) retval, logdev);
+            SDL_UnlockRWLock(current_audio.device_hash_lock);
+            if (!inserted) {
+                SDL_CloseAudioDevice(retval);
+                retval = 0;
+            }
         }
     }