From cdc2162522bb8611701113144f48e91b29337464 Mon Sep 17 00:00:00 2001 From: Randell Jesup Date: Sun, 28 Sep 2014 12:07:24 -0400 Subject: [PATCH] Bug 1072780: patch 1 - clean up CurrentDriver() use off-MSG-thread; fix InCallback() r=roc --- content/media/GraphDriver.cpp | 7 ++++++- content/media/MediaStreamGraph.cpp | 22 ++++++++++++---------- content/media/MediaStreamGraphImpl.h | 13 +++++++++++++ 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/content/media/GraphDriver.cpp b/content/media/GraphDriver.cpp index 3e77d9d19124..4d3818a703dd 100644 --- a/content/media/GraphDriver.cpp +++ b/content/media/GraphDriver.cpp @@ -767,7 +767,12 @@ AudioCallbackDriver::DataCallback(AudioDataValue* aBuffer, long aFrames) return aFrames; } - DebugOnly aic(AutoInCallback(this)); +#ifdef DEBUG + // DebugOnly<> doesn't work here... it forces an initialization that will cause + // mInCallback to be set back to false before we exit the statement. Do it by + // hand instead. + AutoInCallback aic(this); +#endif if (mStateComputedTime == 0) { MonitorAutoLock mon(mGraphImpl->GetMonitor()); diff --git a/content/media/MediaStreamGraph.cpp b/content/media/MediaStreamGraph.cpp index 62faa6cb3b84..70284302c3d6 100644 --- a/content/media/MediaStreamGraph.cpp +++ b/content/media/MediaStreamGraph.cpp @@ -1651,11 +1651,12 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG) // Note that we need to put messages into its queue before reviving it, // or it might exit immediately. { - MonitorAutoUnlock unlock(mMonitor); LIFECYCLE_LOG("Reviving a graph (%p) ! %s\n", this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"); - CurrentDriver()->Revive(); + nsRefPtr driver = CurrentDriver(); + MonitorAutoUnlock unlock(mMonitor); + driver->Revive(); } } } @@ -1671,12 +1672,13 @@ MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG) { // We should exit the monitor for now, because starting a stream might // take locks, and we don't want to deadlock. - MonitorAutoUnlock unlock(mMonitor); LIFECYCLE_LOG("Starting a graph (%p) ! %s\n", this, CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"); - CurrentDriver()->Start(); + nsRefPtr driver = CurrentDriver(); + MonitorAutoUnlock unlock(mMonitor); + driver->Start(); } } @@ -2258,7 +2260,7 @@ SourceMediaStream::SetPullEnabled(bool aEnabled) MutexAutoLock lock(mMutex); mPullEnabled = aEnabled; if (mPullEnabled && GraphImpl()) { - GraphImpl()->CurrentDriver()->EnsureNextIteration(); + GraphImpl()->EnsureNextIteration(); } } @@ -2278,7 +2280,7 @@ SourceMediaStream::AddTrack(TrackID aID, TrackRate aRate, TrackTicks aStart, data->mData = aSegment; data->mHaveEnough = false; if (auto graph = GraphImpl()) { - graph->CurrentDriver()->EnsureNextIteration(); + graph->EnsureNextIteration(); } } @@ -2340,7 +2342,7 @@ SourceMediaStream::AppendToTrack(TrackID aID, MediaSegment* aSegment, MediaSegme NotifyDirectConsumers(track, aRawSegment ? aRawSegment : aSegment); track->mData->AppendFrom(aSegment); // note: aSegment is now dead appended = true; - GraphImpl()->CurrentDriver()->EnsureNextIteration(); + GraphImpl()->EnsureNextIteration(); } else { aSegment->Clear(); } @@ -2464,7 +2466,7 @@ SourceMediaStream::EndTrack(TrackID aID) } } if (auto graph = GraphImpl()) { - graph->CurrentDriver()->EnsureNextIteration(); + graph->EnsureNextIteration(); } } @@ -2475,7 +2477,7 @@ SourceMediaStream::AdvanceKnownTracksTime(StreamTime aKnownTime) MOZ_ASSERT(aKnownTime >= mUpdateKnownTracksTime); mUpdateKnownTracksTime = aKnownTime; if (auto graph = GraphImpl()) { - graph->CurrentDriver()->EnsureNextIteration(); + graph->EnsureNextIteration(); } } @@ -2485,7 +2487,7 @@ SourceMediaStream::FinishWithLockHeld() mMutex.AssertCurrentThreadOwns(); mUpdateFinished = true; if (auto graph = GraphImpl()) { - graph->CurrentDriver()->EnsureNextIteration(); + graph->EnsureNextIteration(); } } diff --git a/content/media/MediaStreamGraphImpl.h b/content/media/MediaStreamGraphImpl.h index ff8c34d5cd61..afc408012d2b 100644 --- a/content/media/MediaStreamGraphImpl.h +++ b/content/media/MediaStreamGraphImpl.h @@ -414,6 +414,9 @@ public: void PausedIndefinitly(); void ResumedFromPaused(); + /** + * Not safe to call off the MediaStreamGraph thread unless monitor is held! + */ GraphDriver* CurrentDriver() { return mDriver; } @@ -432,6 +435,16 @@ public: return mMonitor; } + /** + * Must implement here to avoid dangerous data races around CurrentDriver() - + * we don't want stuff off MSG thread using "graph->CurrentDriver()->EnsureNextIteration()" + * because CurrentDriver may change (and it's a TSAN data race) + */ + void EnsureNextIteration() { + MonitorAutoLock mon(mMonitor); + CurrentDriver()->EnsureNextIterationLocked(); + } + // Data members // /**