Fixed bug 4605 - WASAPI_WaitDevice hang
authorSam Lantinga
Sat, 08 Jun 2019 13:41:46 -0700
changeset 12788bfd1b2fc6e2f
parent 12787 0411f841b035
child 12789 0b44d4aae5fc
Fixed bug 4605 - WASAPI_WaitDevice hang

Matt Brocklehurst

We've noticed that if you are playing audio on Windows via the WASAPI interface and you unplug and reconnect the device a few times the program hangs.

We've debugged the problem down to

static void
WASAPI_WaitDevice(_THIS)
{

... snip ...
if (WaitForSingleObjectEx(this->hidden->event, INFINITE, FALSE) == WAIT_OBJECT_0) {
... snip ...
}

This WaitForSingleObjectEx does not havbe a time out defined, so it hangs there forever.

Our suggested fix we found was to include a time out of say 200mSec

We have done quite a bit of testing with this fix in place on various hardware configurations and it seems to have resolved the issue.
src/audio/wasapi/SDL_wasapi.c
     1.1 --- a/src/audio/wasapi/SDL_wasapi.c	Sat Jun 08 13:36:59 2019 -0700
     1.2 +++ b/src/audio/wasapi/SDL_wasapi.c	Sat Jun 08 13:41:46 2019 -0700
     1.3 @@ -312,8 +312,8 @@
     1.4  WASAPI_WaitDevice(_THIS)
     1.5  {
     1.6      while (RecoverWasapiIfLost(this) && this->hidden->client && this->hidden->event) {
     1.7 -        /*SDL_Log("WAITDEVICE");*/
     1.8 -        if (WaitForSingleObjectEx(this->hidden->event, INFINITE, FALSE) == WAIT_OBJECT_0) {
     1.9 +        DWORD waitResult = WaitForSingleObjectEx(this->hidden->event, 200, FALSE);
    1.10 +        if (waitResult == WAIT_OBJECT_0) {
    1.11              const UINT32 maxpadding = this->spec.samples;
    1.12              UINT32 padding = 0;
    1.13              if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
    1.14 @@ -322,7 +322,7 @@
    1.15                      break;
    1.16                  }
    1.17              }
    1.18 -        } else {
    1.19 +        } else if (waitResult != WAIT_TIMEOUT) {
    1.20              /*SDL_Log("WASAPI FAILED EVENT!");*/
    1.21              IAudioClient_Stop(this->hidden->client);
    1.22              SDL_OpenedAudioDeviceDisconnected(this);