Module: wine
Branch: master
Commit: 7aab8810e19caadd8e32abcbf1a017e115ea8877
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7aab8810e19caadd8e32abcbf…
Author: Nick Burns <adger44(a)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;
}
/*======================================================================*