Module: wine Branch: master Commit: 2a4cab537531104c59e42f48444985dc0f9d5eca URL: http://source.winehq.org/git/wine.git/?a=commit;h=2a4cab537531104c59e42f4844...
Author: Aric Stewart aric@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());