Bug 1196112. Part 2 - Remove DecodedStream::mMonitor. r=roc.
☠☠ backed out by 49879f964c82 ☠ ☠
authorJW Wang <jwwang@mozilla.com>
Mon, 24 Aug 2015 21:05:32 +0800
changeset 259032 b2eb913e58c9c7ddeddb7bdfb95e0846498da514
parent 259031 c678e1317fa0b592169260b7e98a8985abc267ec
child 259033 3e8526f5770624ebf0470679a281d42bed6f35ca
push id29268
push userryanvm@gmail.com
push dateTue, 25 Aug 2015 00:37:23 +0000
treeherdermozilla-central@08015770c9d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1196112
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1196112. Part 2 - Remove DecodedStream::mMonitor. r=roc.
dom/media/DecodedStream.cpp
dom/media/DecodedStream.h
--- a/dom/media/DecodedStream.cpp
+++ b/dom/media/DecodedStream.cpp
@@ -352,17 +352,16 @@ OutputStreamManager::Disconnect()
   }
 }
 
 DecodedStream::DecodedStream(AbstractThread* aOwnerThread,
                              MediaQueue<MediaData>& aAudioQueue,
                              MediaQueue<MediaData>& aVideoQueue)
   : mOwnerThread(aOwnerThread)
   , mShuttingDown(false)
-  , mMonitor("DecodedStream::mMonitor")
   , mPlaying(false)
   , mVolume(1.0)
   , mAudioQueue(aAudioQueue)
   , mVideoQueue(aVideoQueue)
 {
 }
 
 DecodedStream::~DecodedStream()
@@ -376,17 +375,16 @@ DecodedStream::Shutdown()
   MOZ_ASSERT(NS_IsMainThread());
   mShuttingDown = true;
 }
 
 nsRefPtr<GenericPromise>
 DecodedStream::StartPlayback(int64_t aStartTime, const MediaInfo& aInfo)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mStartTime.isNothing(), "playback already started.");
 
   mStartTime.emplace(aStartTime);
   mInfo = aInfo;
   ConnectListener();
 
   class R : public nsRunnable {
     typedef MozPromiseHolder<GenericPromise> Promise;
@@ -414,17 +412,17 @@ DecodedStream::StartPlayback(int64_t aSt
   AbstractThread::MainThread()->Dispatch(r.forget());
 
   return rv.forget();
 }
 
 void DecodedStream::StopPlayback()
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
+
   // Playback didn't even start at all.
   if (mStartTime.isNothing()) {
     return;
   }
 
   mStartTime.reset();
   DisconnectListener();
 
@@ -432,17 +430,16 @@ void DecodedStream::StopPlayback()
   // send data to the wrong stream in SendData() in next playback session.
   DestroyData(Move(mData));
 }
 
 void
 DecodedStream::DestroyData(UniquePtr<DecodedStreamData> aData)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
   if (!aData) {
     return;
   }
 
   DecodedStreamData* data = aData.release();
   nsRefPtr<DecodedStream> self = this;
   nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction([=] () {
@@ -451,17 +448,16 @@ DecodedStream::DestroyData(UniquePtr<Dec
   });
   AbstractThread::MainThread()->Dispatch(r.forget());
 }
 
 void
 DecodedStream::CreateData(MozPromiseHolder<GenericPromise>&& aPromise)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
   // No need to create a source stream when there are no output streams. This
   // happens when RemoveOutput() is called immediately after StartPlayback().
   // Also we don't create a source stream when MDSM has begun shutdown.
   if (!mOutputStreamManager.Graph() || mShuttingDown) {
     // Resolve the promise to indicate the end of playback.
     aPromise.Resolve(true, __func__);
     return;
@@ -499,81 +495,70 @@ DecodedStream::HasConsumers() const
 {
   return !mOutputStreamManager.IsEmpty();
 }
 
 void
 DecodedStream::OnDataCreated(UniquePtr<DecodedStreamData> aData)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(!mData, "Already created.");
 
   // Start to send data to the stream immediately
   if (mStartTime.isSome()) {
     aData->SetPlaying(mPlaying);
     mData = Move(aData);
     SendData();
     return;
   }
 
   // Playback has ended. Destroy aData which is not needed anymore.
   DestroyData(Move(aData));
 }
 
-ReentrantMonitor&
-DecodedStream::GetReentrantMonitor() const
-{
-  return mMonitor;
-}
-
 void
 DecodedStream::AddOutput(ProcessedMediaStream* aStream, bool aFinishWhenEnded)
 {
   mOutputStreamManager.Add(aStream, aFinishWhenEnded);
 }
 
 void
 DecodedStream::RemoveOutput(MediaStream* aStream)
 {
   mOutputStreamManager.Remove(aStream);
 }
 
 void
 DecodedStream::SetPlaying(bool aPlaying)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mPlaying = aPlaying;
   if (mData) {
     mData->SetPlaying(aPlaying);
   }
 }
 
 void
 DecodedStream::SetVolume(double aVolume)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mVolume = aVolume;
 }
 
 void
 DecodedStream::SetSameOrigin(bool aSameOrigin)
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   mSameOrigin = aSameOrigin;
 }
 
 void
 DecodedStream::InitTracks()
 {
   AssertOwnerThread();
-  GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (mData->mStreamInitialized) {
     return;
   }
 
   SourceMediaStream* sourceStream = mData->mStream;
 
   if (mInfo.HasAudio()) {
@@ -644,17 +629,16 @@ SendStreamAudio(DecodedStreamData* aStre
 
   aStream->mNextAudioTime = audio->GetEndTime();
 }
 
 void
 DecodedStream::SendAudio(double aVolume, bool aIsSameOrigin)
 {
   AssertOwnerThread();
-  GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (!mInfo.HasAudio()) {
     return;
   }
 
   AudioSegment output;
   uint32_t rate = mInfo.mAudio.mRate;
   nsAutoTArray<nsRefPtr<MediaData>,10> audio;
@@ -710,17 +694,16 @@ ZeroDurationAtLastChunk(VideoSegment& aI
   aInput.GetLastFrame(&lastVideoStratTime);
   return lastVideoStratTime == aInput.GetDuration();
 }
 
 void
 DecodedStream::SendVideo(bool aIsSameOrigin)
 {
   AssertOwnerThread();
-  GetReentrantMonitor().AssertCurrentThreadIn();
 
   if (!mInfo.HasVideo()) {
     return;
   }
 
   VideoSegment output;
   TrackID videoTrackId = mInfo.mVideo.mTrackId;
   nsAutoTArray<nsRefPtr<MediaData>, 10> video;
@@ -789,17 +772,16 @@ DecodedStream::SendVideo(bool aIsSameOri
     mData->mHaveSentFinishVideo = true;
   }
 }
 
 void
 DecodedStream::AdvanceTracks()
 {
   AssertOwnerThread();
-  GetReentrantMonitor().AssertCurrentThreadIn();
 
   StreamTime endPosition = 0;
 
   if (mInfo.HasAudio()) {
     StreamTime audioEnd = mData->mStream->TicksToTimeRoundDown(
         mInfo.mAudio.mRate, mData->mAudioFramesWritten);
     endPosition = std::max(endPosition, audioEnd);
   }
@@ -814,17 +796,16 @@ DecodedStream::AdvanceTracks()
     mData->mStream->AdvanceKnownTracksTime(endPosition);
   }
 }
 
 void
 DecodedStream::SendData()
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   MOZ_ASSERT(mStartTime.isSome(), "Must be called after StartPlayback()");
 
   // Not yet created on the main thread. MDSM will try again later.
   if (!mData) {
     return;
   }
 
   // Nothing to do when the stream is finished.
@@ -845,67 +826,62 @@ DecodedStream::SendData()
     mData->mStream->Finish();
   }
 }
 
 int64_t
 DecodedStream::AudioEndTime() const
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   if (mStartTime.isSome() && mInfo.HasAudio() && mData) {
     CheckedInt64 t = mStartTime.ref() +
       FramesToUsecs(mData->mAudioFramesWritten, mInfo.mAudio.mRate);
     if (t.isValid()) {
       return t.value();
     }
   }
   return -1;
 }
 
 int64_t
 DecodedStream::GetPosition() const
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   // This is only called after MDSM starts playback. So mStartTime is
   // guaranteed to be something.
   MOZ_ASSERT(mStartTime.isSome());
   return mStartTime.ref() + (mData ? mData->GetPosition() : 0);
 }
 
 bool
 DecodedStream::IsFinished() const
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
   return mData && mData->IsFinished();
 }
 
 void
 DecodedStream::ConnectListener()
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
   mAudioPushListener = mAudioQueue.PushEvent().Connect(
     mOwnerThread, this, &DecodedStream::SendData);
   mAudioFinishListener = mAudioQueue.FinishEvent().Connect(
     mOwnerThread, this, &DecodedStream::SendData);
   mVideoPushListener = mVideoQueue.PushEvent().Connect(
     mOwnerThread, this, &DecodedStream::SendData);
   mVideoFinishListener = mVideoQueue.FinishEvent().Connect(
     mOwnerThread, this, &DecodedStream::SendData);
 }
 
 void
 DecodedStream::DisconnectListener()
 {
   AssertOwnerThread();
-  ReentrantMonitorAutoEnter mon(GetReentrantMonitor());
 
   mAudioPushListener.Disconnect();
   mVideoPushListener.Disconnect();
   mAudioFinishListener.Disconnect();
   mVideoFinishListener.Disconnect();
 }
 
 } // namespace mozilla
--- a/dom/media/DecodedStream.h
+++ b/dom/media/DecodedStream.h
@@ -129,17 +129,16 @@ public:
   int64_t GetPosition() const;
   bool IsFinished() const;
   bool HasConsumers() const;
 
 protected:
   virtual ~DecodedStream();
 
 private:
-  ReentrantMonitor& GetReentrantMonitor() const;
   void CreateData(MozPromiseHolder<GenericPromise>&& aPromise);
   void DestroyData(UniquePtr<DecodedStreamData> aData);
   void OnDataCreated(UniquePtr<DecodedStreamData> aData);
   void InitTracks();
   void AdvanceTracks();
   void SendAudio(double aVolume, bool aIsSameOrigin);
   void SendVideo(bool aIsSameOrigin);
   void SendData();
@@ -156,25 +155,16 @@ private:
   /*
    * Main thread only members.
    */
   // Data about MediaStreams that are being fed by the decoder.
   OutputStreamManager mOutputStreamManager;
   // True if MDSM has begun shutdown.
   bool mShuttingDown;
 
-  // 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;
-
   /*
    * Worker thread only members.
    */
   UniquePtr<DecodedStreamData> mData;
 
   bool mPlaying;
   double mVolume;
   bool mSameOrigin;