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

Alexandre Julliard julliard at winehq.org
Mon May 14 14:26:03 CDT 2012


Module: wine
Branch: master
Commit: a6dbc28bfed6666fc200ec66553a52fed5de379e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=a6dbc28bfed6666fc200ec66553a52fed5de379e

Author: Aric Stewart <aric at 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);




More information about the wine-cvs mailing list