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
This commit is contained in:
Jean-Yves Avenard 2016-05-16 18:30:19 +08:00
Родитель 9225d32861
Коммит 94d52db9f7
3 изменённых файлов: 14 добавлений и 22 удалений

Просмотреть файл

@ -23,7 +23,8 @@ public:
Abort,
Reset,
RangeRemoval,
EvictData
EvictData,
Detach
};
typedef Pair<bool, SourceBufferAttributes> 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

Просмотреть файл

@ -99,7 +99,6 @@ TrackBuffersManager::TrackBuffersManager(MediaSourceDecoder* aParentDecoder,
, mTaskQueue(aParentDecoder->GetDemuxer()->GetTaskQueue())
, mParentDecoder(new nsMainThreadPtrHolder<MediaSourceDecoder>(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<AppendBufferTask>()->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));
}

Просмотреть файл

@ -397,9 +397,6 @@ private:
// Set to true if mediasource state changed to ended.
Atomic<bool> mEnded;
// Set to true if the parent SourceBuffer has shutdown.
// We will not reschedule or process new task once mDetached is set.
Atomic<bool> mDetached;
// Global size of this source buffer content.
Atomic<int64_t> mSizeSourceBuffer;