mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-03 08:28:29 +00:00
wasapi: Don't proxy device disconnect to the WASAPI management thread.
It gets proxied to the main thread, now. Fixes deadlocks when unplugging a playing USB audio device.
This commit is contained in:
@@ -164,21 +164,10 @@ bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, b
|
||||
return true; // successfully added (and possibly executed)!
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_AudioDeviceDisconnected(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_AudioDeviceDisconnected(device);
|
||||
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
|
||||
return true;
|
||||
}
|
||||
|
||||
static void AudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
{
|
||||
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (device) {
|
||||
RefPhysicalAudioDevice(device); // make sure this lives until the task completes.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_AudioDeviceDisconnected, device, NULL);
|
||||
}
|
||||
WASAPI_DisconnectDevice(device);
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_DefaultAudioDeviceChanged(void *userdata)
|
||||
@@ -351,19 +340,11 @@ static void WASAPI_DetectDevices(SDL_AudioDevice **default_playback, SDL_AudioDe
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_DetectDevices, &data, &rc);
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_DisconnectDevice(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_AudioDeviceDisconnected(device);
|
||||
UnrefPhysicalAudioDevice(device);
|
||||
return true;
|
||||
}
|
||||
|
||||
void WASAPI_DisconnectDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
if (SDL_CompareAndSwapAtomicInt(&device->hidden->device_disconnecting, 0, 1)) {
|
||||
RefPhysicalAudioDevice(device); // will unref when the task ends.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_DisconnectDevice, device, NULL);
|
||||
// don't block in here; IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (device->hidden && SDL_CompareAndSwapAtomicInt(&device->hidden->device_disconnecting, 0, 1)) {
|
||||
SDL_AudioDeviceDisconnected(device); // this proxies the work to the main thread now, so no point in proxying to the management thread.
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user