audio: Assert that all devices from device_hash are the appropriate type

The keys and values of device_hash are pairs
`(SDL_AudioDeviceID devid, void *dev)` where dev can be either a
`SDL_AudioDevice *` or a `SDL_LogicalAudioDevice *`, depending on
bit 1 of devid.

We can confirm that we have got this right by looking at the
instance_id member, because logical audio devices happen to start with
the devid, whereas physical devices start with a pointer which is
unlikely to match the devid by chance.

Signed-off-by: Simon McVittie <smcv@collabora.com>
(cherry picked from commit 70b2d162e3)
This commit is contained in:
Simon McVittie
2025-05-13 13:09:43 +01:00
committed by Sam Lantinga
parent 01ef4c46a1
commit 71bd25a893

View File

@@ -410,6 +410,7 @@ static SDL_LogicalAudioDevice *ObtainLogicalAudioDevice(SDL_AudioDeviceID devid,
SDL_LockRWLockForReading(current_audio.device_hash_lock); SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev); SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &logdev);
if (logdev) { if (logdev) {
SDL_assert(logdev->instance_id == devid);
device = logdev->physical_device; device = logdev->physical_device;
SDL_assert(device != NULL); SDL_assert(device != NULL);
RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default. RefPhysicalAudioDevice(device); // reference it, in case the logical device migrates to a new default.
@@ -459,6 +460,7 @@ static SDL_AudioDevice *ObtainPhysicalAudioDevice(SDL_AudioDeviceID devid) // !
} else { } else {
SDL_LockRWLockForReading(current_audio.device_hash_lock); SDL_LockRWLockForReading(current_audio.device_hash_lock);
SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device); SDL_FindInHashTable(current_audio.device_hash, (const void *) (uintptr_t) devid, (const void **) &device);
SDL_assert(device->instance_id == devid);
SDL_UnlockRWLock(current_audio.device_hash_lock); SDL_UnlockRWLock(current_audio.device_hash_lock);
if (!device) { if (!device) {
@@ -883,6 +885,7 @@ static bool SDLCALL FindLowestDeviceID(void *userdata, const SDL_HashTable *tabl
if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) { if (isphysical && (devid_recording == data->recording) && (devid < data->highest)) {
data->highest = devid; data->highest = devid;
data->result = (SDL_AudioDevice *) value; data->result = (SDL_AudioDevice *) value;
SDL_assert(data->result->instance_id == devid);
} }
return true; // keep iterating. return true; // keep iterating.
} }
@@ -1051,7 +1054,10 @@ static bool SDLCALL DestroyOnePhysicalAudioDevice(void *userdata, const SDL_Hash
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key; const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (uintptr_t) key;
const bool isphysical = !!(devid & (1<<1)); const bool isphysical = !!(devid & (1<<1));
if (isphysical) { if (isphysical) {
DestroyPhysicalAudioDevice((SDL_AudioDevice *) value); SDL_AudioDevice *dev = (SDL_AudioDevice *) value;
SDL_assert(dev->instance_id == devid);
DestroyPhysicalAudioDevice(dev);
} }
return true; // keep iterating. return true; // keep iterating.
} }
@@ -1464,6 +1470,7 @@ static bool SDLCALL FindAudioDeviceByCallback(void *userdata, const SDL_HashTabl
SDL_AudioDevice *device = (SDL_AudioDevice *) value; SDL_AudioDevice *device = (SDL_AudioDevice *) value;
if (data->callback(device, data->userdata)) { // found it? if (data->callback(device, data->userdata)) { // found it?
data->retval = device; data->retval = device;
SDL_assert(data->retval->instance_id == devid);
return false; // stop iterating, we found it. return false; // stop iterating, we found it.
} }
} }
@@ -1520,9 +1527,11 @@ const char *SDL_GetAudioDeviceName(SDL_AudioDeviceID devid)
SDL_SetError("Invalid audio device instance ID"); SDL_SetError("Invalid audio device instance ID");
} else if (islogical) { } else if (islogical) {
const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev; const SDL_LogicalAudioDevice *logdev = (const SDL_LogicalAudioDevice *) vdev;
SDL_assert(logdev->instance_id == devid);
result = SDL_GetPersistentString(logdev->physical_device->name); result = SDL_GetPersistentString(logdev->physical_device->name);
} else { } else {
const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev; const SDL_AudioDevice *device = (const SDL_AudioDevice *) vdev;
SDL_assert(device->instance_id == devid);
result = SDL_GetPersistentString(device->name); result = SDL_GetPersistentString(device->name);
} }
SDL_UnlockRWLock(current_audio.device_hash_lock); SDL_UnlockRWLock(current_audio.device_hash_lock);