=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: winecoreaudio: Avoid deadlock in AudioClient_Stop.
Alexandre Julliard
julliard at winehq.org
Tue Jan 31 14:06:19 CST 2012
Module: wine
Branch: master
Commit: c99501197425ca0bbda04465da0c23ea76fe73a7
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c99501197425ca0bbda04465da0c23ea76fe73a7
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Sun Jan 15 20:16:51 2012 +0100
winecoreaudio: Avoid deadlock in AudioClient_Stop.
---
dlls/winecoreaudio.drv/mmdevdrv.c | 22 ++++++++++++++++++----
1 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/dlls/winecoreaudio.drv/mmdevdrv.c b/dlls/winecoreaudio.drv/mmdevdrv.c
index 07359c0..52fdef0 100644
--- a/dlls/winecoreaudio.drv/mmdevdrv.c
+++ b/dlls/winecoreaudio.drv/mmdevdrv.c
@@ -1440,8 +1440,12 @@ static HRESULT WINAPI AudioClient_Start(IAudioClient *iface)
if(This->event)
if(!CreateTimerQueueTimer(&This->timer, g_timer_q,
- ca_period_cb, This, 0, This->period_ms, 0))
- ERR("Unable to create timer: %u\n", GetLastError());
+ ca_period_cb, This, 0, This->period_ms, 0)){
+ This->timer = NULL;
+ OSSpinLockUnlock(&This->lock);
+ WARN("Unable to create timer: %u\n", GetLastError());
+ return E_OUTOFMEMORY;
+ }
This->playing = StateInTransition;
@@ -1467,6 +1471,8 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
ACImpl *This = impl_from_IAudioClient(iface);
AudioTimeStamp tstamp;
OSStatus sc;
+ HANDLE event = NULL;
+ BOOL wait = FALSE;
TRACE("(%p)\n", This);
@@ -1487,9 +1493,13 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
return S_OK;
}
- if(This->timer && This->timer != INVALID_HANDLE_VALUE){
- DeleteTimerQueueTimer(g_timer_q, This->timer, INVALID_HANDLE_VALUE);
+ if(This->timer){
+ event = CreateEventW(NULL, TRUE, FALSE, NULL);
+ wait = !DeleteTimerQueueTimer(g_timer_q, This->timer, event);
This->timer = NULL;
+ if(wait)
+ WARN("DeleteTimerQueueTimer error %u\n", GetLastError());
+ wait = wait && GetLastError() == ERROR_IO_PENDING;
}
This->playing = StateInTransition;
@@ -1506,6 +1516,10 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
OSSpinLockUnlock(&This->lock);
+ if(event && wait)
+ WaitForSingleObject(event, INFINITE);
+ CloseHandle(event);
+
sc = AudioQueueFlush(This->aqueue);
if(sc != noErr)
WARN("Unable to flush audio queue: %lx\n", sc);
More information about the wine-cvs
mailing list