Aric Stewart : wineqtdecoder: Properly clean up splitter and loader threads on QTSplitter destruction.

Alexandre Julliard julliard at winehq.org
Tue Nov 20 13:52:23 CST 2012


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

Author: Aric Stewart <aric at codeweavers.com>
Date:   Tue Nov 20 08:08:36 2012 -0600

wineqtdecoder: Properly clean up splitter and loader threads on QTSplitter destruction.

---

 dlls/wineqtdecoder/qtsplitter.c |   56 +++++++++++++++++++++++++++++---------
 1 files changed, 42 insertions(+), 14 deletions(-)

diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index b584198..a3cd91f 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -168,6 +168,9 @@ typedef struct QTSplitter {
     TimeValue movie_time;
     TimeValue movie_start;
     TimeScale movie_scale;
+
+    HANDLE loaderThread;
+    HANDLE splitterThread;
 } QTSplitter;
 
 static const IPinVtbl QT_OutputPin_Vtbl;
@@ -293,6 +296,7 @@ static void QT_Destroy(QTSplitter *This)
 
     TRACE("Destroying\n");
 
+    EnterCriticalSection(&This->csReceive);
     /* Don't need to clean up output pins, disconnecting input pin will do that */
     IPin_ConnectedTo(&This->pInputPin.pin.IPin_iface, &connected);
     if (connected)
@@ -311,14 +315,31 @@ static void QT_Destroy(QTSplitter *This)
     }
 
     if (This->pQTMovie)
+    {
         DisposeMovie(This->pQTMovie);
+        This->pQTMovie = NULL;
+    }
     if (This->vContext)
         QTVisualContextRelease(This->vContext);
     if (This->aSession)
         MovieAudioExtractionEnd(This->aSession);
-    CloseHandle(This->runEvent);
 
     ExitMovies();
+    LeaveCriticalSection(&This->csReceive);
+
+    if (This->loaderThread)
+    {
+        WaitForSingleObject(This->loaderThread, INFINITE);
+        CloseHandle(This->loaderThread);
+    }
+    if (This->splitterThread)
+    {
+        SetEvent(This->runEvent);
+        WaitForSingleObject(This->splitterThread, INFINITE);
+        CloseHandle(This->splitterThread);
+    }
+
+    CloseHandle(This->runEvent);
 
     This->csReceive.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&This->csReceive);
@@ -495,13 +516,15 @@ static DWORD WINAPI QTSplitter_loading_thread(LPVOID data)
             to try to minimize that.
          */
 
-        while(GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete)
+        EnterCriticalSection(&This->csReceive);
+        while(This->pQTMovie && GetMovieLoadState(This->pQTMovie) < kMovieLoadStateComplete)
         {
-            EnterCriticalSection(&This->csReceive);
             MoviesTask(This->pQTMovie, 100);
             LeaveCriticalSection(&This->csReceive);
             Sleep(0);
+            EnterCriticalSection(&This->csReceive);
         }
+        LeaveCriticalSection(&This->csReceive);
     }
     return 0;
 }
@@ -518,6 +541,12 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
     WaitForSingleObject(This->runEvent, -1);
 
     EnterCriticalSection(&This->csReceive);
+    if (!This->pQTMovie)
+    {
+        LeaveCriticalSection(&This->csReceive);
+        return 0;
+    }
+
     This->state = State_Running;
     /* Prime the pump:  Needed for MPEG streams */
     GetMovieNextInterestingTime(This->pQTMovie, nextTimeEdgeOK | nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL);
@@ -536,6 +565,12 @@ static DWORD WINAPI QTSplitter_thread(LPVOID data)
         float time;
 
         EnterCriticalSection(&This->csReceive);
+        if (!This->pQTMovie)
+        {
+            LeaveCriticalSection(&This->csReceive);
+            return 0;
+        }
+
         GetMovieNextInterestingTime(This->pQTMovie, nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL);
 
         if (next_time == -1)
@@ -992,7 +1027,6 @@ static HRESULT QT_Process_Movie(QTSplitter* filter)
     Track trk;
     short id = 0;
     DWORD tid;
-    HANDLE thread;
     LONGLONG time;
 
     TRACE("Trying movie connect\n");
@@ -1039,18 +1073,12 @@ static HRESULT QT_Process_Movie(QTSplitter* filter)
 
     TRACE("Movie duration is %s\n",wine_dbgstr_longlong(filter->sourceSeeking.llDuration));
 
-    thread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid);
-    if (thread)
-    {
+    filter->loaderThread = CreateThread(NULL, 0, QTSplitter_loading_thread, filter, 0, &tid);
+    if (filter->loaderThread)
         TRACE("Created loading thread 0x%08x\n", tid);
-        CloseHandle(thread);
-    }
-    thread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
-    if (thread)
-    {
+    filter->splitterThread = CreateThread(NULL, 0, QTSplitter_thread, filter, 0, &tid);
+    if (filter->splitterThread)
         TRACE("Created processing thread 0x%08x\n", tid);
-        CloseHandle(thread);
-    }
     else
         hr = HRESULT_FROM_WIN32(GetLastError());
 




More information about the wine-cvs mailing list