From 94d52db9f7e0c7d75d4155c0d0d8c3f7462255e7 Mon Sep 17 00:00:00 2001 From: Jean-Yves Avenard Date: Mon, 16 May 2016 18:30:19 +0800 Subject: [PATCH] Bug 1264694: [MSE] P2. Clear mTaskQueue early when no longer required. r=jwwang We need to ensure that the MSE TaskQueue gets shutdown as soon as possible and not wait for the MediaSource parent to be destroyed by the cycle collector. XPCOM shutdown will deadlock if any SharedThreadPool are still in use, and it possible for the cycle collector to only occur after xpcom has shutdown. So it's important to ensure mTaskQueue is cleared when the MediaSourceDecoder has been shutdown. This is done by queueing a new DetachTask that will clear mTaskQueue when run. MozReview-Commit-ID: C3FXcRtq1wy --HG-- extra : rebase_source : 79a7c5cb451655c4679b9d4e11d0b5ca0d9814b9 --- dom/media/mediasource/SourceBufferTask.h | 9 ++++++- dom/media/mediasource/TrackBuffersManager.cpp | 24 +++++-------------- dom/media/mediasource/TrackBuffersManager.h | 3 --- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/dom/media/mediasource/SourceBufferTask.h b/dom/media/mediasource/SourceBufferTask.h index db42774a0d76..2ba8ea0ef627 100644 --- a/dom/media/mediasource/SourceBufferTask.h +++ b/dom/media/mediasource/SourceBufferTask.h @@ -23,7 +23,8 @@ public: Abort, Reset, RangeRemoval, - EvictData + EvictData, + Detach }; typedef Pair AppendBufferResult; @@ -98,6 +99,12 @@ public: int64_t mSizeToEvict; }; +class DetachTask : public SourceBufferTask { +public: + static const Type sType = Type::Detach; + Type GetType() const override { return Type::Detach; } +}; + } // end mozilla namespace #endif \ No newline at end of file diff --git a/dom/media/mediasource/TrackBuffersManager.cpp b/dom/media/mediasource/TrackBuffersManager.cpp index a80abb3bb9f5..b9e5bb7d7445 100644 --- a/dom/media/mediasource/TrackBuffersManager.cpp +++ b/dom/media/mediasource/TrackBuffersManager.cpp @@ -99,7 +99,6 @@ TrackBuffersManager::TrackBuffersManager(MediaSourceDecoder* aParentDecoder, , mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue()) , mParentDecoder(new nsMainThreadPtrHolder(aParentDecoder, false /* strict */)) , mEnded(false) - , mDetached(false) , mVideoEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold.video", 100 * 1024 * 1024)) , mAudioEvictionThreshold(Preferences::GetUint("media.mediasource.eviction_threshold.audio", @@ -162,10 +161,6 @@ TrackBuffersManager::ProcessTasks() MOZ_ASSERT(OnTaskQueue()); typedef SourceBufferTask::Type Type; - if (mDetached) { - return; - } - if (mCurrentTask) { // Already have a task pending. ProcessTask will be scheduled once the // current task complete. @@ -208,6 +203,11 @@ TrackBuffersManager::ProcessTasks() case Type::Reset: CompleteResetParserState(); break; + case Type::Detach: + mTaskQueue = nullptr; + MOZ_DIAGNOSTIC_ASSERT(mQueue.Length() == 0, + "Detach task must be the last"); + return; default: NS_WARNING("Invalid Task"); } @@ -223,7 +223,6 @@ void TrackBuffersManager::CancelAllTasks() { typedef SourceBufferTask::Type Type; - MOZ_DIAGNOSTIC_ASSERT(mDetached); if (mCurrentTask) { mQueue.Push(mCurrentTask); @@ -388,7 +387,7 @@ TrackBuffersManager::Detach() { MOZ_ASSERT(NS_IsMainThread()); MSE_DEBUG(""); - mDetached = true; + QueueTask(new DetachTask()); } void @@ -757,10 +756,6 @@ void TrackBuffersManager::NeedMoreData() { MSE_DEBUG(""); - if (mDetached) { - // We've been detached. - return; - } MOZ_DIAGNOSTIC_ASSERT(mCurrentTask && mCurrentTask->GetType() == SourceBufferTask::Type::AppendBuffer); MOZ_DIAGNOSTIC_ASSERT(mSourceBufferAttributes); @@ -777,10 +772,6 @@ void TrackBuffersManager::RejectAppend(nsresult aRejectValue, const char* aName) { MSE_DEBUG("rv=%d", aRejectValue); - if (mDetached) { - // We've been detached. - return; - } MOZ_DIAGNOSTIC_ASSERT(mCurrentTask && mCurrentTask->GetType() == SourceBufferTask::Type::AppendBuffer); mCurrentTask->As()->mPromise.Reject(aRejectValue, __func__); @@ -792,9 +783,6 @@ TrackBuffersManager::RejectAppend(nsresult aRejectValue, const char* aName) void TrackBuffersManager::ScheduleSegmentParserLoop() { - if (mDetached) { - return; - } GetTaskQueue()->Dispatch(NewRunnableMethod(this, &TrackBuffersManager::SegmentParserLoop)); } diff --git a/dom/media/mediasource/TrackBuffersManager.h b/dom/media/mediasource/TrackBuffersManager.h index 26c4a7c0a5b0..73575f3ea6ae 100644 --- a/dom/media/mediasource/TrackBuffersManager.h +++ b/dom/media/mediasource/TrackBuffersManager.h @@ -397,9 +397,6 @@ private: // Set to true if mediasource state changed to ended. Atomic mEnded; - // Set to true if the parent SourceBuffer has shutdown. - // We will not reschedule or process new task once mDetached is set. - Atomic mDetached; // Global size of this source buffer content. Atomic mSizeSourceBuffer;