Module: wine Branch: master Commit: 7aab8810e19caadd8e32abcbf1a017e115ea8877 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7aab8810e19caadd8e32abcbf1...
Author: Nick Burns adger44@hotmail.com Date: Mon Jan 1 02:22:58 2007 -0800
winecoreaudio: Fix race condition in drvclose.
---
dlls/winmm/winecoreaudio/audio.c | 17 +++++++++++++++-- 1 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/winmm/winecoreaudio/audio.c b/dlls/winmm/winecoreaudio/audio.c index 455a365..4723928 100644 --- a/dlls/winmm/winecoreaudio/audio.c +++ b/dlls/winmm/winecoreaudio/audio.c @@ -207,6 +207,7 @@ typedef struct { static WINE_WAVEOUT WOutDev [MAX_WAVEOUTDRV]; static WINE_WAVEIN WInDev [MAX_WAVEINDRV];
+static HANDLE hThread = NULL; /* Track the thread we create so we can clean it up later */ static CFMessagePortRef Port_SendToMessageThread;
static void wodHelper_PlayPtrNext(WINE_WAVEOUT* wwo); @@ -327,7 +328,7 @@ static DWORD WINAPI messageThread(LPVOID
source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, port_ReceiveInMessageThread, (CFIndex)0); CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); - + CFRunLoopRun();
CFRunLoopSourceInvalidate(source); @@ -499,7 +500,6 @@ LONG CoreAudio_WaveInit(void) UInt32 propertySize; CHAR szPname[MAXPNAMELEN]; int i; - HANDLE hThread; CFStringRef messageThreadPortName; CFMessagePortRef port_ReceiveInMessageThread; int inputSampleRate; @@ -665,6 +665,13 @@ LONG CoreAudio_WaveInit(void) return 1; }
+ /* Cannot WAIT for any events because we are called from the loader (which has a lock on loading stuff) */ + /* We might want to wait for this thread to be created -- but we cannot -- not here at least */ + /* Instead track the thread so we can clean it up later */ + if ( hThread ) + { + ERR("Message thread already started -- expect problems\n"); + } hThread = CreateThread(NULL, 0, messageThread, (LPVOID)port_ReceiveInMessageThread, 0, NULL); if ( !hThread ) { @@ -688,6 +695,12 @@ void CoreAudio_WaveRelease(void) CFMessagePortSendRequest(Port_SendToMessageThread, kStopLoopMessage, NULL, 0.0, 0.0, NULL, NULL); CFRelease(Port_SendToMessageThread); Port_SendToMessageThread = NULL; + + /* Wait for the thread to finish and clean it up */ + /* This rids us of any quick start/shutdown driver crashes */ + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + hThread = NULL; }
/*======================================================================*