Jörg Höhle : winealsa: Avoid deadlock in AudioClient_Stop.
Alexandre Julliard
julliard at winehq.org
Tue Jun 21 12:25:41 CDT 2011
Module: wine
Branch: master
Commit: 8db18a893b3769d482f22bd2e2b545b82a31574f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8db18a893b3769d482f22bd2e2b545b82a31574f
Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date: Thu Jun 16 00:37:59 2011 +0200
winealsa: Avoid deadlock in AudioClient_Stop.
---
dlls/winealsa.drv/mmdevdrv.c | 26 +++++++++++++++++++-------
1 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/dlls/winealsa.drv/mmdevdrv.c b/dlls/winealsa.drv/mmdevdrv.c
index abb2d39..236ae40 100644
--- a/dlls/winealsa.drv/mmdevdrv.c
+++ b/dlls/winealsa.drv/mmdevdrv.c
@@ -1472,13 +1472,15 @@ static void CALLBACK alsa_push_buffer_data(void *user, BOOLEAN timer)
EnterCriticalSection(&This->lock);
- if(This->dataflow == eRender && This->held_frames)
- alsa_write_data(This);
- else if(This->dataflow == eCapture)
- alsa_read_data(This);
+ if(This->started){
+ if(This->dataflow == eRender && This->held_frames)
+ alsa_write_data(This);
+ else if(This->dataflow == eCapture)
+ alsa_read_data(This);
- if(This->event)
- SetEvent(This->event);
+ if(This->event)
+ SetEvent(This->event);
+ }
LeaveCriticalSection(&This->lock);
}
@@ -1567,6 +1569,8 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
{
ACImpl *This = impl_from_IAudioClient(iface);
int err;
+ HANDLE event;
+ BOOL wait;
TRACE("(%p)\n", This);
@@ -1582,7 +1586,11 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
return S_FALSE;
}
- DeleteTimerQueueTimer(g_timer_q, This->timer, INVALID_HANDLE_VALUE);
+ event = CreateEventW(NULL, TRUE, FALSE, NULL);
+ wait = !DeleteTimerQueueTimer(g_timer_q, This->timer, event);
+ if(wait)
+ WARN("DeleteTimerQueueTimer error %u\n", GetLastError());
+ wait = wait && GetLastError() == ERROR_IO_PENDING;
if((err = snd_pcm_drop(This->pcm_handle)) < 0){
LeaveCriticalSection(&This->lock);
@@ -1600,6 +1608,10 @@ static HRESULT WINAPI AudioClient_Stop(IAudioClient *iface)
LeaveCriticalSection(&This->lock);
+ if(event && wait)
+ WaitForSingleObject(event, INFINITE);
+ CloseHandle(event);
+
return S_OK;
}
More information about the wine-cvs
mailing list