winecoreaudio.drv: Ensure divide-by-zero SSE exceptions are masked before calling AudioConverterNew.

AudioConverterNew can trigger a divide-by-zero exception. Normally this
is masked by the default SSE mask flags. However, iRacing disables this
mask, leading to a crash when it tries to initialize a recording device.

Signed-off-by: Andrew Eikum <aeikum@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Andrew Eikum 2016-03-25 08:26:11 -05:00 committed by Alexandre Julliard
parent d05edd03c4
commit 8efa49375a
1 changed files with 13 additions and 0 deletions

View File

@ -36,6 +36,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <fcntl.h> #include <fcntl.h>
#include <fenv.h>
#include <unistd.h> #include <unistd.h>
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
@ -1233,6 +1234,8 @@ static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance uni
AudioStreamBasicDescription desc; AudioStreamBasicDescription desc;
UInt32 size; UInt32 size;
Float64 rate; Float64 rate;
fenv_t fenv;
BOOL fenv_stored = TRUE;
hr = ca_get_audiodesc(&desc, fmt); hr = ca_get_audiodesc(&desc, fmt);
if(FAILED(hr)) if(FAILED(hr))
@ -1262,7 +1265,17 @@ static HRESULT ca_setup_audiounit(EDataFlow dataflow, AudioComponentInstance uni
return osstatus_to_hresult(sc); return osstatus_to_hresult(sc);
} }
/* AudioConverterNew requires divide-by-zero SSE exceptions to be masked */
if(feholdexcept(&fenv)){
WARN("Failed to store fenv state\n");
fenv_stored = FALSE;
}
sc = AudioConverterNew(dev_desc, &desc, converter); sc = AudioConverterNew(dev_desc, &desc, converter);
if(fenv_stored && fesetenv(&fenv))
WARN("Failed to restore fenv state\n");
if(sc != noErr){ if(sc != noErr){
WARN("Couldn't create audio converter: %x\n", (int)sc); WARN("Couldn't create audio converter: %x\n", (int)sc);
return osstatus_to_hresult(sc); return osstatus_to_hresult(sc);