Skip to content

Commit 39aff4c

Browse files
committed
audio: Pass the id, not the obj, to SDL_AudioDeviceDisconnected_OnMainThread.
If a device has disconnected, and the app has quit the audio subsystem before the queued main thread function has run, the pointer will be bogus by the time the run occurs. So now it looks up the object from its device ID, and if the lookup returns NULL, it returns immediately and everything works out. Reference Issue #14856. (which might be fixed by this or not.) (cherry picked from commit 774728b)
1 parent 2d8ddf3 commit 39aff4c

1 file changed

Lines changed: 6 additions & 6 deletions

File tree

src/audio/SDL_audio.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,11 @@ static void SetAudioDeviceZombieFunctions(SDL_AudioDevice *device)
754754
// Called when a device is removed from the system, or it fails unexpectedly, from any thread, possibly even the audio device's thread.
755755
static void SDLCALL SDL_AudioDeviceDisconnected_OnMainThread(void *userdata)
756756
{
757-
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
758-
SDL_assert(device != NULL);
757+
const SDL_AudioDeviceID devid = (SDL_AudioDeviceID) (size_t) userdata;
758+
SDL_AudioDevice *device = ObtainPhysicalAudioDevice(devid);
759+
if (device == NULL) {
760+
return; // apparently it went away already.
761+
}
759762

760763
// Save off removal info in a list so we can send events for each, next
761764
// time the event queue pumps, in case something tries to close a device
@@ -765,10 +768,7 @@ static void SDLCALL SDL_AudioDeviceDisconnected_OnMainThread(void *userdata)
765768
pending.next = NULL;
766769
SDL_PendingAudioDeviceEvent *pending_tail = &pending;
767770

768-
ObtainPhysicalAudioDeviceObj(device);
769-
770771
SDL_LockRWLockForReading(current_audio.subsystem_rwlock);
771-
const SDL_AudioDeviceID devid = device->instance_id;
772772
const bool is_default_device = ((devid == current_audio.default_playback_device_id) || (devid == current_audio.default_recording_device_id));
773773
SDL_UnlockRWLock(current_audio.subsystem_rwlock);
774774

@@ -835,7 +835,7 @@ void SDL_AudioDeviceDisconnected(SDL_AudioDevice *device)
835835
if (device) {
836836
RefPhysicalAudioDevice(device);
837837
SDL_CompareAndSwapAtomicInt(&device->zombie, 0, 1); // note that we're (un)dead right now, if we haven't already, but leave the event notifications for the main thread.
838-
SDL_RunOnMainThread(SDL_AudioDeviceDisconnected_OnMainThread, device, false);
838+
SDL_RunOnMainThread(SDL_AudioDeviceDisconnected_OnMainThread, (void *) (size_t) device->instance_id, false);
839839
}
840840
}
841841

0 commit comments

Comments
 (0)