Module: wine Branch: master Commit: a6dbc28bfed6666fc200ec66553a52fed5de379e URL: http://source.winehq.org/git/wine.git/?a=commit;h=a6dbc28bfed6666fc200ec6655...
Author: Aric Stewart aric@codeweavers.com Date: Fri May 11 13:21:07 2012 -0500
quartz: Handle a crash and race condition that occurs on directsound renderer input pin disconnect.
---
dlls/quartz/dsoundrender.c | 54 +++++++++++++++++++++++++------------------ 1 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 696f0a2..0b5463e 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -527,7 +527,9 @@ static HRESULT WINAPI DSoundRender_BreakConnect(BaseRenderer* iface)
if (This->threadid) { PostThreadMessageW(This->threadid, WM_APP, 0, 0); + LeaveCriticalSection(This->renderer.pInputPin->pin.pCritSec); WaitForSingleObject(This->advisethread, INFINITE); + EnterCriticalSection(This->renderer.pInputPin->pin.pCritSec); CloseHandle(This->advisethread); } if (This->dsbuffer) @@ -931,28 +933,26 @@ static DWORD WINAPI DSoundAdviseThread(LPVOID lpParam) { struct dsoundrender_timer *prev = &head, *cur;
hr = IReferenceClock_GetTime(&This->IReferenceClock_iface, &curtime); - if (FAILED(hr)) { - FIXME("Could not get time: %08x\n", hr); - continue; - } - TRACE("Time: %s\n", wine_dbgstr_longlong(curtime)); - while (prev->next) { - cur = prev->next; - if (cur->start > curtime) { - TRACE("Skipping %p\n", cur); - prev = cur; - } else if (cur->periodicity) { - while (cur->start <= curtime) { - cur->start += cur->periodicity; - ReleaseSemaphore(cur->handle, 1, NULL); + if (SUCCEEDED(hr)) { + TRACE("Time: %s\n", wine_dbgstr_longlong(curtime)); + while (prev->next) { + cur = prev->next; + if (cur->start > curtime) { + TRACE("Skipping %p\n", cur); + prev = cur; + } else if (cur->periodicity) { + while (cur->start <= curtime) { + cur->start += cur->periodicity; + ReleaseSemaphore(cur->handle, 1, NULL); + } + prev = cur; + } else { + struct dsoundrender_timer *next = cur->next; + TRACE("Firing %p %s < %s\n", cur, wine_dbgstr_longlong(cur->start), wine_dbgstr_longlong(curtime)); + SetEvent(cur->handle); + HeapFree(GetProcessHeap(), 0, cur); + prev->next = next; } - prev = cur; - } else { - struct dsoundrender_timer *next = cur->next; - TRACE("Firing %p %s < %s\n", cur, wine_dbgstr_longlong(cur->start), wine_dbgstr_longlong(curtime)); - SetEvent(cur->handle); - HeapFree(GetProcessHeap(), 0, cur); - prev->next = next; } } if (!head.next) @@ -1039,9 +1039,17 @@ static HRESULT WINAPI ReferenceClock_GetTime(IReferenceClock *iface, DWORD writepos1, writepos2; EnterCriticalSection(&This->renderer.filter.csFilter); DSoundRender_UpdatePositions(This, &writepos1, &writepos2); - *pTime = This->play_time + time_from_pos(This, This->last_playpos); + if (This->renderer.pInputPin && This->renderer.pInputPin->pin.mtCurrent.pbFormat) + { + *pTime = This->play_time + time_from_pos(This, This->last_playpos); + hr = S_OK; + } + else + { + ERR("pInputPin Disconncted\n"); + hr = E_FAIL; + } LeaveCriticalSection(&This->renderer.filter.csFilter); - hr = S_OK; } if (FAILED(hr)) WARN("Could not get reference time (%x)!\n", hr);