ensure SDL_AUDIODEVICEREMOVED gets sent when hotplug removes a device
authorSam Lantinga
Tue, 04 Oct 2016 06:48:07 -0700
changeset 10467be888d570cc8
parent 10466 b7267e214a77
child 10468 9f14a7dfaa6a
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
src/audio/SDL_sysaudio.h
     1.1 --- a/src/audio/SDL_audio.c	Tue Oct 04 06:46:46 2016 -0700
     1.2 +++ b/src/audio/SDL_audio.c	Tue Oct 04 06:48:07 2016 -0700
     1.3 @@ -408,13 +408,26 @@
     1.4  void
     1.5  SDL_RemoveAudioDevice(const int iscapture, void *handle)
     1.6  {
     1.7 +    int device_index;
     1.8 +    SDL_AudioDevice *device = NULL;
     1.9 +
    1.10      SDL_LockMutex(current_audio.detectionLock);
    1.11      if (iscapture) {
    1.12          mark_device_removed(handle, current_audio.inputDevices, &current_audio.captureDevicesRemoved);
    1.13      } else {
    1.14          mark_device_removed(handle, current_audio.outputDevices, &current_audio.outputDevicesRemoved);
    1.15      }
    1.16 +    for (device_index = 0; device_index < SDL_arraysize(open_devices); device_index++)
    1.17 +    {
    1.18 +        device = open_devices[device_index];
    1.19 +        if (device != NULL && device->handle == handle)
    1.20 +        {
    1.21 +            SDL_OpenedAudioDeviceDisconnected(device);
    1.22 +            break;
    1.23 +        }
    1.24 +    }
    1.25      SDL_UnlockMutex(current_audio.detectionLock);
    1.26 +
    1.27      current_audio.impl.FreeDeviceHandle(handle);
    1.28  }
    1.29  
    1.30 @@ -1254,6 +1267,7 @@
    1.31      device->id = id + 1;
    1.32      device->spec = *obtained;
    1.33      device->iscapture = iscapture ? SDL_TRUE : SDL_FALSE;
    1.34 +    device->handle = handle;
    1.35  
    1.36      SDL_AtomicSet(&device->shutdown, 0);  /* just in case. */
    1.37      SDL_AtomicSet(&device->paused, 1);
     2.1 --- a/src/audio/SDL_sysaudio.h	Tue Oct 04 06:46:46 2016 -0700
     2.2 +++ b/src/audio/SDL_sysaudio.h	Tue Oct 04 06:48:07 2016 -0700
     2.3 @@ -187,6 +187,8 @@
     2.4      /* * * */
     2.5      /* Data private to this driver */
     2.6      struct SDL_PrivateAudioData *hidden;
     2.7 +
     2.8 +    void *handle;
     2.9  };
    2.10  #undef _THIS
    2.11