From 96a12f389c285d1bdbb7a5e5ceb74c85895898ca Mon Sep 17 00:00:00 2001 From: JW Wang Date: Sun, 11 May 2014 20:12:00 +0200 Subject: [PATCH] Bug 1004669 - Fix leaks in MediaTaskQueue::Dispatch(). r=cpearce --- content/media/MediaDecoderStateMachine.cpp | 19 +++++++++---------- content/media/MediaTaskQueue.cpp | 2 +- content/media/MediaTaskQueue.h | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/content/media/MediaDecoderStateMachine.cpp b/content/media/MediaDecoderStateMachine.cpp index 9e6089f8b421..cdd9c9d91909 100644 --- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -245,14 +245,9 @@ MediaDecoderStateMachine::~MediaDecoderStateMachine() NS_ASSERTION(!mPendingWakeDecoder.get(), "WakeDecoder should have been revoked already"); - if (mDecodeTaskQueue) { - mDecodeTaskQueue->Shutdown(); - mDecodeTaskQueue = nullptr; - } - - // No need to cancel the timer here for we've done that in - // TimeoutExpired() triggered by Shutdown() - mTimer = nullptr; + MOZ_ASSERT(!mDecodeTaskQueue, "Should be released in SHUTDOWN"); + // No need to cancel the timer here for we've done that in SHUTDOWN. + MOZ_ASSERT(!mTimer, "Should be released in SHUTDOWN"); mReader = nullptr; #ifdef XP_WIN @@ -1584,13 +1579,13 @@ MediaDecoderStateMachine::DispatchDecodeTasksIfNeeded() return; } mIsReaderIdle = needIdle; - nsRefPtr event; + RefPtr event; if (mIsReaderIdle) { event = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::SetReaderIdle); } else { event = NS_NewRunnableMethod(this, &MediaDecoderStateMachine::SetReaderActive); } - if (NS_FAILED(mDecodeTaskQueue->Dispatch(event)) && + if (NS_FAILED(mDecodeTaskQueue->Dispatch(event.forget())) && mState != DECODER_STATE_SHUTDOWN) { NS_WARNING("Failed to dispatch event to set decoder idle state"); } @@ -2149,6 +2144,7 @@ nsresult MediaDecoderStateMachine::RunStateMachine() ReentrantMonitorAutoExit exitMon(mDecoder->GetReentrantMonitor()); // Wait for the thread decoding to exit. mDecodeTaskQueue->Shutdown(); + mDecodeTaskQueue = nullptr; mReader->ReleaseMediaResources(); } // Now that those threads are stopped, there's no possibility of @@ -2172,6 +2168,9 @@ nsresult MediaDecoderStateMachine::RunStateMachine() // state machine. GetStateMachineThread()->Dispatch( new nsDispatchDisposeEvent(mDecoder, this), NS_DISPATCH_NORMAL); + + mTimer->Cancel(); + mTimer = nullptr; return NS_OK; } diff --git a/content/media/MediaTaskQueue.cpp b/content/media/MediaTaskQueue.cpp index f3741d3aaff5..d523895d79f5 100644 --- a/content/media/MediaTaskQueue.cpp +++ b/content/media/MediaTaskQueue.cpp @@ -27,7 +27,7 @@ MediaTaskQueue::~MediaTaskQueue() } nsresult -MediaTaskQueue::Dispatch(nsIRunnable* aRunnable) +MediaTaskQueue::Dispatch(TemporaryRef aRunnable) { MonitorAutoLock mon(mQueueMonitor); if (mIsShutdown) { diff --git a/content/media/MediaTaskQueue.h b/content/media/MediaTaskQueue.h index 3cf860c3c5ae..2c695e4bb19b 100644 --- a/content/media/MediaTaskQueue.h +++ b/content/media/MediaTaskQueue.h @@ -31,7 +31,7 @@ public: MediaTaskQueue(TemporaryRef aPool); - nsresult Dispatch(nsIRunnable* aRunnable); + nsresult Dispatch(TemporaryRef aRunnable); // Removes all pending tasks from the task queue, and blocks until // the currently running task (if any) finishes.