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

Fixes #8395.
main
Ryan C. Gordon 2023-10-14 23:10:50 -04:00
parent e526dc64bd
commit b22ffb9797
No known key found for this signature in database
GPG Key ID: FA148B892AB48044
1 changed files with 22 additions and 12 deletions

View File

@ -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! // 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) static void DestroyLogicalAudioDevice(SDL_LogicalAudioDevice *logdev)
{ {
// 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_LockRWLockForWriting(current_audio.device_hash_lock);
SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) logdev->instance_id); SDL_RemoveFromHashTable(current_audio.device_hash, (const void *) (uintptr_t) logdev->instance_id);
SDL_UnlockRWLock(current_audio.device_hash_lock); SDL_UnlockRWLock(current_audio.device_hash_lock);
}
// remove ourselves from the physical device's list of logical devices. // remove ourselves from the physical device's list of logical devices.
if (logdev->next) { if (logdev->next) {
@ -773,10 +776,15 @@ void SDL_QuitAudio(void)
const void *value; const void *value;
void *iter = NULL; void *iter = NULL;
while (SDL_IterateHashTable(device_hash, &key, &value, &iter)) { while (SDL_IterateHashTable(device_hash, &key, &value, &iter)) {
// 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_AudioDevice *device = (SDL_AudioDevice *) value;
SDL_AtomicSet(&device->shutdown, 1); SDL_AtomicSet(&device->shutdown, 1);
DestroyPhysicalAudioDevice(device); DestroyPhysicalAudioDevice(device);
} }
}
// Free the driver data // Free the driver data
current_audio.impl.Deinitialize(); current_audio.impl.Deinitialize();
@ -1513,6 +1521,7 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
} }
SDL_UnlockMutex(device->lock); SDL_UnlockMutex(device->lock);
if (retval) {
SDL_LockRWLockForWriting(current_audio.device_hash_lock); SDL_LockRWLockForWriting(current_audio.device_hash_lock);
const SDL_bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) retval, logdev); const SDL_bool inserted = SDL_InsertIntoHashTable(current_audio.device_hash, (const void *) (uintptr_t) retval, logdev);
SDL_UnlockRWLock(current_audio.device_hash_lock); SDL_UnlockRWLock(current_audio.device_hash_lock);
@ -1521,6 +1530,7 @@ SDL_AudioDeviceID SDL_OpenAudioDevice(SDL_AudioDeviceID devid, const SDL_AudioSp
retval = 0; retval = 0;
} }
} }
}
return retval; return retval;
} }