diff --git a/dom/media/DecodedStream.cpp b/dom/media/DecodedStream.cpp index e7c98486218..8eff602a620 100644 --- a/dom/media/DecodedStream.cpp +++ b/dom/media/DecodedStream.cpp @@ -193,8 +193,8 @@ OutputStreamData::Init(DecodedStream* aDecodedStream, ProcessedMediaStream* aStr aStream->AddListener(mListener); } -DecodedStream::DecodedStream(ReentrantMonitor& aMonitor) - : mMonitor(aMonitor) +DecodedStream::DecodedStream() + : mMonitor("DecodedStream::mMonitor") { // } @@ -202,7 +202,7 @@ DecodedStream::DecodedStream(ReentrantMonitor& aMonitor) DecodedStreamData* DecodedStream::GetData() const { - GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); return mData.get(); } @@ -210,7 +210,7 @@ void DecodedStream::DestroyData() { MOZ_ASSERT(NS_IsMainThread()); - GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); // Avoid the redundant blocking to output stream. if (!mData) { @@ -245,7 +245,7 @@ void DecodedStream::RecreateData(MediaStreamGraph* aGraph) { MOZ_ASSERT(NS_IsMainThread()); - GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); MOZ_ASSERT((aGraph && !mData && OutputStreams().IsEmpty()) || // first time (!aGraph && mData)); // 2nd time and later @@ -300,7 +300,7 @@ void DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded) { MOZ_ASSERT(NS_IsMainThread()); - GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); OutputStreamData* os = OutputStreams().AppendElement(); os->Init(this, aStream); @@ -314,7 +314,7 @@ DecodedStream::Connect(ProcessedMediaStream* aStream, bool aFinishWhenEnded) void DecodedStream::SetPlaying(bool aPlaying) { - GetReentrantMonitor().AssertCurrentThreadIn(); + ReentrantMonitorAutoEnter mon(GetReentrantMonitor()); MOZ_ASSERT(mData); mData->SetPlaying(aPlaying); } diff --git a/dom/media/DecodedStream.h b/dom/media/DecodedStream.h index 748576c9826..4117dd1cff4 100644 --- a/dom/media/DecodedStream.h +++ b/dom/media/DecodedStream.h @@ -85,7 +85,7 @@ public: class DecodedStream { public: - explicit DecodedStream(ReentrantMonitor& aMonitor); + DecodedStream(); DecodedStreamData* GetData() const; void DestroyData(); void RecreateData(MediaStreamGraph* aGraph); @@ -100,7 +100,15 @@ private: UniquePtr mData; // Data about MediaStreams that are being fed by the decoder. nsTArray mOutputStreams; - ReentrantMonitor& mMonitor; + + // TODO: This is a temp solution to get rid of decoder monitor on the main + // thread in MDSM::AddOutputStream and MDSM::RecreateDecodedStream as + // required by bug 1146482. DecodedStream needs to release monitor before + // calling back into MDSM functions in order to prevent deadlocks. + // + // Please move all capture-stream related code from MDSM into DecodedStream + // and apply "dispatch + mirroring" to get rid of this monitor in the future. + mutable ReentrantMonitor mMonitor; }; } // namespace mozilla diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index bea799ab3aa..3106cd47735 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -237,8 +237,7 @@ MediaDecoderStateMachine::MediaDecoderStateMachine(MediaDecoder* aDecoder, mDecodingFrozenAtStateDecoding(false), mSentLoadedMetadataEvent(false), mSentFirstFrameLoadedEvent(false), - mSentPlaybackEndedEvent(false), - mDecodedStream(mDecoder->GetReentrantMonitor()) + mSentPlaybackEndedEvent(false) { MOZ_COUNT_CTOR(MediaDecoderStateMachine); NS_ASSERTION(NS_IsMainThread(), "Should be on main thread."); @@ -3348,7 +3347,6 @@ uint32_t MediaDecoderStateMachine::GetAmpleVideoFrames() const DecodedStreamData* MediaDecoderStateMachine::GetDecodedStream() const { - AssertCurrentThreadInMonitor(); return mDecodedStream.GetData(); } @@ -3382,7 +3380,6 @@ void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream, MOZ_ASSERT(NS_IsMainThread()); DECODER_LOG("AddOutputStream aStream=%p!", aStream); - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); if (!GetDecodedStream()) { RecreateDecodedStream(aStream->Graph()); } @@ -3393,9 +3390,15 @@ void MediaDecoderStateMachine::AddOutputStream(ProcessedMediaStream* aStream, void MediaDecoderStateMachine::RecreateDecodedStream(MediaStreamGraph* aGraph) { MOZ_ASSERT(NS_IsMainThread()); - ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); mDecodedStream.RecreateData(aGraph); - mDecodedStream.SetPlaying(IsPlaying()); + + nsRefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction([self] () -> void + { + ReentrantMonitorAutoEnter mon(self->mDecoder->GetReentrantMonitor()); + self->mDecodedStream.SetPlaying(self->IsPlaying()); + }); + TaskQueue()->Dispatch(r.forget()); } } // namespace mozilla