Commit a6dbc28b authored by Aric Stewart's avatar Aric Stewart Committed by Alexandre Julliard

quartz: Handle a crash and race condition that occurs on directsound renderer input pin disconnect.

parent fb42513a
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment