From bac61096d81bee4d832c91476f6480bf9e962f18 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 4 Oct 2016 06:48:07 -0700 Subject: [PATCH] ensure SDL_AUDIODEVICEREMOVED gets sent when hotplug removes a device James Zipperer The problem I was seeing was that the the ALSA hotplug thread would call SDL_RemoveAudioDevice, but my application code was not seeing an SDL_AUDIODEVICEREMOVED event to go along with it. To fix it, I added some code into SDL_RemoveAudioDevice to call SDL_OpenedAudioDeviceDisconnected on the corresponding open audio device. There didn't appear to be a way to cross reference the handle that SDL_RemoveAudioDevice gets and the SDL_AudioDevice pointer that SDL_OpenedAudioDeviceDisconnected needs, so I ended up adding a void *handle field to struct SDL_AudioDevice so that I could do the cross reference. Is there some other way beside adding a void *handle field to the struct to get the proper information for SDL_OpenedAudioDeviceDisconnected? --- src/audio/SDL_audio.c | 14 ++++++++++++++ src/audio/SDL_sysaudio.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c index f9cd73610..9749a2d82 100644 --- a/src/audio/SDL_audio.c +++ b/src/audio/SDL_audio.c @@ -408,13 +408,26 @@ mark_device_removed(void *handle, SDL_AudioDeviceItem *devices, SDL_bool *remove void SDL_RemoveAudioDevice(const int iscapture, void *handle) { + int device_index; + SDL_AudioDevice *device = NULL; + SDL_LockMutex(current_audio.detectionLock); if (iscapture) { mark_device_removed(handle, current_audio.inputDevices, ¤t_audio.captureDevicesRemoved); } else { mark_device_removed(handle, current_audio.outputDevices, ¤t_audio.outputDevicesRemoved); } + for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++) + { + device = open_devices[device_index]; + if (device != NULL && device->handle == handle) + { + SDL_OpenedAudioDeviceDisconnected(device); + break; + } + } SDL_UnlockMutex(current_audio.detectionLock); + current_audio.impl.FreeDeviceHandle(handle); } @@ -1254,6 +1267,7 @@ open_audio_device(const char *devname, int iscapture, device->id = id + 1; device->spec = *obtained; device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE; + device->handle = handle; SDL_AtomicSet(&device->shutdown, 0); /* just in case. */ SDL_AtomicSet(&device->paused, 1); diff --git a/src/audio/SDL_sysaudio.h b/src/audio/SDL_sysaudio.h index 1bb1324ab..73a2cfb11 100644 --- a/src/audio/SDL_sysaudio.h +++ b/src/audio/SDL_sysaudio.h @@ -187,6 +187,8 @@ struct SDL_AudioDevice /* * * */ /* Data private to this driver */ struct SDL_PrivateAudioData *hidden; + + void *handle; }; #undef _THIS