Module: wine Branch: master Commit: 8db18a893b3769d482f22bd2e2b545b82a31574f URL: http://source.winehq.org/git/wine.git/?a=commit;h=8db18a893b3769d482f22bd2e2...
Author: Jörg Höhle hoehle@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; }