Bug 1415556 - P3. clearly mark functions' thread use. r=padenot
authorJean-Yves Avenard <jyavenard@mozilla.com>
Fri, 10 Nov 2017 18:24:20 +0100
changeset 436574 cfc4191ade585351c1a3f5759f34f3e67b86b92f
parent 436573 44b20d160436d290d7f5b22f4644af980888b5ff
child 436575 e5e283e7055ffebc9ec354ee94804c97c1078ff1
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewerspadenot
bugs1415556
milestone59.0a1
Bug 1415556 - P3. clearly mark functions' thread use. r=padenot MozReview-Commit-ID: BXmdk4zBo28
dom/media/MediaStreamGraph.cpp
dom/media/MediaStreamGraph.h
dom/media/MediaStreamGraphImpl.h
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -61,25 +61,26 @@ enum SourceMediaStream::TrackCommands : 
  * A hash table containing the graph instances, one per document.
  *
  * The key is a hash of nsPIDOMWindowInner, see `WindowToHash`.
  */
 static nsDataHashtable<nsUint32HashKey, MediaStreamGraphImpl*> gGraphs;
 
 MediaStreamGraphImpl::~MediaStreamGraphImpl()
 {
-  NS_ASSERTION(IsEmpty(),
-               "All streams should have been destroyed by messages from the main thread");
+  MOZ_ASSERT(mStreams.IsEmpty() && mSuspendedStreams.IsEmpty(),
+             "All streams should have been destroyed by messages from the main thread");
   LOG(LogLevel::Debug, ("MediaStreamGraph %p destroyed", this));
   LOG(LogLevel::Debug, ("MediaStreamGraphImpl::~MediaStreamGraphImpl"));
 }
 
 void
 MediaStreamGraphImpl::FinishStream(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   if (aStream->mFinished)
     return;
   LOG(LogLevel::Debug, ("MediaStream %p will finish", aStream));
 #ifdef DEBUG
   for (StreamTracks::TrackIter track(aStream->mTracks);
          !track.IsEnded(); track.Next()) {
     if (!track->IsEnded()) {
       LOG(LogLevel::Error,
@@ -94,16 +95,17 @@ MediaStreamGraphImpl::FinishStream(Media
   aStream->mTracks.AdvanceKnownTracksTime(STREAM_TIME_MAX);
 
   SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::AddStreamGraphThread(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   aStream->mTracksStartTime = mProcessedTime;
 
   if (aStream->AsSourceStream()) {
     SourceMediaStream* source = aStream->AsSourceStream();
     TimeStamp currentTimeStamp = CurrentDriver()->GetCurrentTimeStamp();
     TimeStamp processedTimeStamp = currentTimeStamp +
       TimeDuration::FromSeconds(MediaTimeToSeconds(mProcessedTime - IterationEnd()));
     source->SetStreamTracksStartTimeStamp(processedTimeStamp);
@@ -129,16 +131,17 @@ MediaStreamGraphImpl::AddStreamGraphThre
   }
 
   SetStreamOrderDirty();
 }
 
 void
 MediaStreamGraphImpl::RemoveStreamGraphThread(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   // Remove references in mStreamUpdates before we allow aStream to die.
   // Pending updates are not needed (since the main thread has already given
   // up the stream) so we will just drop them.
   {
     MonitorAutoLock lock(mMonitor);
     for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
       if (mStreamUpdates[i].mStream == aStream) {
         mStreamUpdates[i].mStream = nullptr;
@@ -169,16 +172,17 @@ MediaStreamGraphImpl::RemoveStreamGraphT
   NS_RELEASE(aStream); // probably destroying it
 }
 
 void
 MediaStreamGraphImpl::ExtractPendingInput(SourceMediaStream* aStream,
                                           GraphTime aDesiredUpToTime,
                                           bool* aEnsureNextIteration)
 {
+  MOZ_ASSERT(OnGraphThread());
   bool finished;
   {
     MutexAutoLock lock(aStream->mMutex);
     if (aStream->mPullEnabled && !aStream->mFinished &&
         !aStream->mListeners.IsEmpty()) {
       // Compute how much stream time we'll need assuming we don't block
       // the stream at all.
       StreamTime t = aStream->GraphTimeToStreamTime(aDesiredUpToTime);
@@ -326,22 +330,24 @@ MediaStreamGraphImpl::GraphTimeToStreamT
              "Don't ask about times where we haven't made blocking decisions yet");
   return std::max<StreamTime>(0,
       std::min(aTime, aStream->mStartBlocking) - aStream->mTracksStartTime);
 }
 
 GraphTime
 MediaStreamGraphImpl::IterationEnd() const
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   return CurrentDriver()->IterationEnd();
 }
 
 void
 MediaStreamGraphImpl::UpdateCurrentTimeForStreams(GraphTime aPrevCurrentTime)
 {
+  MOZ_ASSERT(OnGraphThread());
   for (MediaStream* stream : AllStreams()) {
     bool isAnyBlocked = stream->mStartBlocking < mStateComputedTime;
     bool isAnyUnblocked = stream->mStartBlocking > aPrevCurrentTime;
 
     // Calculate blocked time and fire Blocked/Unblocked events
     GraphTime blockedTime = mStateComputedTime - stream->mStartBlocking;
     NS_ASSERTION(blockedTime >= 0, "Error in blocking time");
     stream->AdvanceTimeVaryingValuesToCurrentTime(mStateComputedTime,
@@ -395,16 +401,17 @@ MediaStreamGraphImpl::UpdateCurrentTimeF
 template<typename C, typename Chunk>
 void
 MediaStreamGraphImpl::ProcessChunkMetadataForInterval(MediaStream* aStream,
                                                       TrackID aTrackID,
                                                       C& aSegment,
                                                       StreamTime aStart,
                                                       StreamTime aEnd)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   MOZ_ASSERT(aStream);
   MOZ_ASSERT(IsTrackIDExplicit(aTrackID));
 
   StreamTime offset = 0;
   for (typename C::ConstChunkIterator chunk(aSegment);
          !chunk.IsEnded(); chunk.Next()) {
     if (offset >= aEnd) {
       break;
@@ -431,16 +438,17 @@ MediaStreamGraphImpl::ProcessChunkMetada
       }
     }
   }
 }
 
 void
 MediaStreamGraphImpl::ProcessChunkMetadata(GraphTime aPrevCurrentTime)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   for (MediaStream* stream : AllStreams()) {
     StreamTime iterationStart = stream->GraphTimeToStreamTime(aPrevCurrentTime);
     StreamTime iterationEnd = stream->GraphTimeToStreamTime(mProcessedTime);
     for (StreamTracks::TrackIter tracks(stream->mTracks);
             !tracks.IsEnded(); tracks.Next()) {
       MediaSegment* segment = tracks->GetSegment();
       if (!segment) {
         continue;
@@ -498,17 +506,17 @@ namespace {
   const uint32_t NOT_VISITED = UINT32_MAX;
   // Value of mCycleMarker for ordered streams in muted cycles.
   const uint32_t IN_MUTED_CYCLE = 1;
 } // namespace
 
 bool
 MediaStreamGraphImpl::AudioTrackPresent(bool& aNeedsAEC)
 {
-  AssertOnGraphThreadOrNotRunning();
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
 
   bool audioTrackPresent = false;
   for (uint32_t i = 0; i < mStreams.Length() && audioTrackPresent == false; ++i) {
     MediaStream* stream = mStreams[i];
     SourceMediaStream* source = stream->AsSourceStream();
 #ifdef MOZ_WEBRTC
     if (source && source->NeedsMixing()) {
       aNeedsAEC = true;
@@ -540,16 +548,17 @@ MediaStreamGraphImpl::AudioTrackPresent(
   }
 
   return audioTrackPresent;
 }
 
 void
 MediaStreamGraphImpl::UpdateStreamOrder()
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   bool shouldAEC = false;
   bool audioTrackPresent = AudioTrackPresent(shouldAEC);
 
   // Note that this looks for any audio streams, input or output, and switches to a
   // SystemClockDriver if there are none.  However, if another is already pending, let that
   // switch happen.
 
   if (!audioTrackPresent && mRealtime &&
@@ -775,16 +784,17 @@ MediaStreamGraphImpl::NotifyHasCurrentDa
     }
     aStream->mNotifiedHasCurrentData = true;
   }
 }
 
 void
 MediaStreamGraphImpl::CreateOrDestroyAudioStreams(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   MOZ_ASSERT(mRealtime, "Should only attempt to create audio streams in real-time mode");
 
   if (aStream->mAudioOutputs.IsEmpty()) {
     aStream->mAudioOutputStreams.Clear();
     return;
   }
 
   if (!aStream->GetStreamTracks().GetAndResetTracksDirty() &&
@@ -841,16 +851,17 @@ MediaStreamGraphImpl::CreateOrDestroyAud
       aStream->mAudioOutputStreams.RemoveElementAt(i);
     }
   }
 }
 
 StreamTime
 MediaStreamGraphImpl::PlayAudio(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   MOZ_ASSERT(mRealtime, "Should only attempt to play audio in realtime mode");
 
   float volume = 0.0f;
   for (uint32_t i = 0; i < aStream->mAudioOutputs.Length(); ++i) {
     volume += aStream->mAudioOutputs[i].mVolume;
   }
 
   StreamTime ticksWritten = 0;
@@ -956,16 +967,17 @@ MediaStreamGraphImpl::PlayAudio(MediaStr
   }
   return ticksWritten;
 }
 
 void
 MediaStreamGraphImpl::OpenAudioInputImpl(int aID,
                                          AudioDataListener *aListener)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   // Bug 1238038 Need support for multiple mics at once
   if (mInputDeviceUsers.Count() > 0 &&
       !mInputDeviceUsers.Get(aListener, nullptr)) {
     NS_ASSERTION(false, "Input from multiple mics not yet supported; bug 1238038");
     // Need to support separate input-only AudioCallback drivers; they'll
     // call us back on "other" threads.  We will need to echo-cancel them, though.
     return;
   }
@@ -1037,16 +1049,17 @@ MediaStreamGraphImpl::OpenAudioInput(int
   // XXX Check not destroyed!
   this->AppendMessage(MakeUnique<Message>(this, aID, aListener));
   return NS_OK;
 }
 
 void
 MediaStreamGraphImpl::CloseAudioInputImpl(AudioDataListener *aListener)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   uint32_t count;
   DebugOnly<bool> result = mInputDeviceUsers.Get(aListener, &count);
   MOZ_ASSERT(result);
   if (--count > 0) {
     mInputDeviceUsers.Put(aListener, count);
     return; // still in use
   }
   mInputDeviceUsers.Remove(aListener);
@@ -1120,39 +1133,50 @@ MediaStreamGraph::NotifyOutputData(Audio
 bool
 MediaStreamGraph::OnGraphThreadOrNotRunning() const
 {
   // either we're on the right thread (and calling CurrentDriver() is safe),
   // or we're going to fail the assert anyway, so don't cross-check
   // via CurrentDriver().
   MediaStreamGraphImpl const * graph =
     static_cast<MediaStreamGraphImpl const *>(this);
-  // if all the safety checks fail, assert we own the monitor
   return graph->mDetectedNotRunning ?
     NS_IsMainThread() : graph->mDriver->OnThread();
 }
 
 bool
+MediaStreamGraph::OnGraphThread() const
+{
+  // we're on the right thread (and calling mDriver is safe),
+  MediaStreamGraphImpl const * graph =
+    static_cast<MediaStreamGraphImpl const *>(this);
+  MOZ_ASSERT(graph->mDriver);
+  return graph->mDriver->OnThread();
+}
+
+bool
 MediaStreamGraphImpl::ShouldUpdateMainThread()
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   if (mRealtime) {
     return true;
   }
 
   TimeStamp now = TimeStamp::Now();
   if ((now - mLastMainThreadUpdate).ToMilliseconds() > CurrentDriver()->IterationDuration()) {
     mLastMainThreadUpdate = now;
     return true;
   }
   return false;
 }
 
 void
 MediaStreamGraphImpl::PrepareUpdatesToMainThreadState(bool aFinalUpdate)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   mMonitor.AssertCurrentThreadOwns();
 
   // We don't want to frequently update the main thread about timing update
   // when we are not running in realtime.
   if (aFinalUpdate || ShouldUpdateMainThread()) {
     // Strip updates that will be obsoleted below, so as to keep the length of
     // mStreamUpdates sane.
     size_t keptUpdateCount = 0;
@@ -1211,16 +1235,17 @@ MediaStreamGraphImpl::RoundUpToNextAudio
   StreamTime nextTicks = nextBlock << WEBAUDIO_BLOCK_SIZE_BITS;
   return nextTicks;
 }
 
 void
 MediaStreamGraphImpl::ProduceDataForStreamsBlockByBlock(uint32_t aStreamIndex,
                                                         TrackRate aSampleRate)
 {
+  MOZ_ASSERT(OnGraphThread());
   MOZ_ASSERT(aStreamIndex <= mFirstCycleBreaker,
              "Cycle breaker is not AudioNodeStream?");
   GraphTime t = mProcessedTime;
   while (t < mStateComputedTime) {
     GraphTime next = RoundUpToNextAudioBlock(t);
     for (uint32_t i = mFirstCycleBreaker; i < mStreams.Length(); ++i) {
       auto ns = static_cast<AudioNodeStream*>(mStreams[i]);
       MOZ_ASSERT(ns->AsAudioNodeStream());
@@ -1237,57 +1262,60 @@ MediaStreamGraphImpl::ProduceDataForStre
   }
   NS_ASSERTION(t == mStateComputedTime,
                "Something went wrong with rounding to block boundaries");
 }
 
 bool
 MediaStreamGraphImpl::AllFinishedStreamsNotified()
 {
+  MOZ_ASSERT(OnGraphThread());
   for (MediaStream* stream : AllStreams()) {
     if (stream->mFinished && !stream->mNotifiedFinished) {
       return false;
     }
   }
   return true;
 }
 
 void
 MediaStreamGraphImpl::RunMessageAfterProcessing(UniquePtr<ControlMessage> aMessage)
 {
-  MOZ_ASSERT(CurrentDriver()->OnThread());
+  MOZ_ASSERT(OnGraphThread());
 
   if (mFrontMessageQueue.IsEmpty()) {
     mFrontMessageQueue.AppendElement();
   }
 
   // Only one block is used for messages from the graph thread.
   MOZ_ASSERT(mFrontMessageQueue.Length() == 1);
   mFrontMessageQueue[0].mMessages.AppendElement(Move(aMessage));
 }
 
 void
 MediaStreamGraphImpl::RunMessagesInQueue()
 {
+  MOZ_ASSERT(OnGraphThread());
   // Calculate independent action times for each batch of messages (each
   // batch corresponding to an event loop task). This isolates the performance
   // of different scripts to some extent.
   for (uint32_t i = 0; i < mFrontMessageQueue.Length(); ++i) {
     nsTArray<UniquePtr<ControlMessage>>& messages = mFrontMessageQueue[i].mMessages;
 
     for (uint32_t j = 0; j < messages.Length(); ++j) {
       messages[j]->Run();
     }
   }
   mFrontMessageQueue.Clear();
 }
 
 void
 MediaStreamGraphImpl::UpdateGraph(GraphTime aEndBlockingDecisions)
 {
+  MOZ_ASSERT(OnGraphThread());
   MOZ_ASSERT(aEndBlockingDecisions >= mProcessedTime);
   // The next state computed time can be the same as the previous: it
   // means the driver would be have been blocking indefinitly, but the graph has
   // been woken up right after having been to sleep.
   MOZ_ASSERT(aEndBlockingDecisions >= mStateComputedTime);
 
   UpdateStreamOrder();
 
@@ -1338,16 +1366,17 @@ MediaStreamGraphImpl::UpdateGraph(GraphT
       aEndBlockingDecisions == mStateComputedTime) {
     EnsureNextIteration();
   }
 }
 
 void
 MediaStreamGraphImpl::Process()
 {
+  MOZ_ASSERT(OnGraphThread());
   // Play stream contents.
   bool allBlockedForever = true;
   // True when we've done ProcessInput for all processed streams.
   bool doneAllProducing = false;
   // This is the number of frame that are written to the AudioStreams, for
   // this cycle.
   StreamTime ticksPlayed = 0;
 
@@ -1419,16 +1448,17 @@ MediaStreamGraphImpl::Process()
   if (!allBlockedForever) {
     EnsureNextIteration();
   }
 }
 
 bool
 MediaStreamGraphImpl::UpdateMainThreadState()
 {
+  MOZ_ASSERT(OnGraphThread());
   MonitorAutoLock lock(mMonitor);
   bool finalUpdate = mForceShutDown ||
     (mProcessedTime >= mEndTime && AllFinishedStreamsNotified()) ||
     (IsEmpty() && mBackMessageQueue.IsEmpty());
   PrepareUpdatesToMainThreadState(finalUpdate);
   if (finalUpdate) {
     // Enter shutdown mode. The stable-state handler will detect this
     // and complete shutdown. Destroy any streams immediately.
@@ -1445,16 +1475,17 @@ MediaStreamGraphImpl::UpdateMainThreadSt
 
   SwapMessageQueues();
   return true;
 }
 
 bool
 MediaStreamGraphImpl::OneIteration(GraphTime aStateEnd)
 {
+  MOZ_ASSERT(OnGraphThread());
   WebCore::DenormalDisabler disabler;
 
   // Process graph message from the main thread for this iteration.
   RunMessagesInQueue();
 
   GraphTime stateEnd = std::min(aStateEnd, mEndTime);
   UpdateGraph(stateEnd);
 
@@ -1474,33 +1505,34 @@ MediaStreamGraphImpl::OneIteration(Graph
   RunMessagesInQueue();
 
   return UpdateMainThreadState();
 }
 
 void
 MediaStreamGraphImpl::ApplyStreamUpdate(StreamUpdate* aUpdate)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   mMonitor.AssertCurrentThreadOwns();
 
   MediaStream* stream = aUpdate->mStream;
   if (!stream)
     return;
   stream->mMainThreadCurrentTime = aUpdate->mNextMainThreadCurrentTime;
   stream->mMainThreadFinished = aUpdate->mNextMainThreadFinished;
 
   if (stream->ShouldNotifyStreamFinished()) {
     stream->NotifyMainThreadListeners();
   }
 }
 
 void
 MediaStreamGraphImpl::ForceShutDown(media::ShutdownTicket* aShutdownTicket)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
+  MOZ_ASSERT(NS_IsMainThread(), "Must be called on main thread");
   LOG(LogLevel::Debug, ("MediaStreamGraph %p ForceShutdown", this));
 
   MonitorAutoLock lock(mMonitor);
   if (aShutdownTicket) {
     MOZ_ASSERT(!mForceShutdownTicket);
     // Avoid waiting forever for a graph to shut down
     // synchronously.  Reports are that some 3rd-party audio drivers
     // occasionally hang in shutdown (both for us and Chrome).
@@ -1520,16 +1552,17 @@ MediaStreamGraphImpl::ForceShutDown(medi
     driver->Start();
   }
   EnsureNextIterationLocked();
 }
 
 NS_IMETHODIMP
 MediaStreamGraphImpl::Notify(nsITimer* aTimer)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   MonitorAutoLock lock(mMonitor);
   NS_ASSERTION(!mForceShutdownTicket, "MediaStreamGraph took too long to shut down!");
   // Sigh, graph took too long to shut down.  Stop blocking system
   // shutdown and hope all is well.
   mForceShutdownTicket = nullptr;
   return NS_OK;
 }
 
@@ -1547,17 +1580,18 @@ namespace {
 class MediaStreamGraphShutDownRunnable : public Runnable {
 public:
   explicit MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph)
     : Runnable("MediaStreamGraphShutDownRunnable")
     , mGraph(aGraph)
   {}
   NS_IMETHOD Run()
   {
-    NS_ASSERTION(mGraph->mDetectedNotRunning,
+    MOZ_ASSERT(NS_IsMainThread());
+    MOZ_ASSERT(mGraph->mDetectedNotRunning && mGraph->mDriver,
                  "We should know the graph thread control loop isn't running!");
 
     LOG(LogLevel::Debug, ("Shutting down graph %p", mGraph.get()));
 
     // We've asserted the graph isn't running.  Use mDriver instead of CurrentDriver
     // to avoid thread-safety checks
 #if 0 // AudioCallbackDrivers are released asynchronously anyways
     // XXX a better test would be have setting mDetectedNotRunning make sure
@@ -1587,16 +1621,17 @@ public:
         "AudioCallbackDriver took too long to shut down and we let shutdown"
         " continue - freezing and leaking");
 
       // The timer fired, so we may be deeper in shutdown now.  Block any further
       // teardown and just leak, for safety.
       return NS_OK;
     }
 
+    // mGraph's thread is not running so it's OK to do whatever here
     for (MediaStream* stream : mGraph->AllStreams()) {
       // Clean up all MediaSegments since we cannot release Images too
       // late during shutdown. Also notify listeners that they were removed
       // so they can clean up any gfx resources.
       if (SourceMediaStream* source = stream->AsSourceStream()) {
         // Finishing a SourceStream prevents new data from being appended.
         source->Finish();
       }
@@ -1605,17 +1640,16 @@ public:
     }
 
     mGraph->mForceShutdownTicket = nullptr;
 
     // We can't block past the final LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION
     // stage, since completion of that stage requires all streams to be freed,
     // which requires shutdown to proceed.
 
-    // mGraph's thread is not running so it's OK to do whatever here
     if (mGraph->IsEmpty()) {
       // mGraph is no longer needed, so delete it.
       mGraph->Destroy();
     } else {
       // The graph is not empty.  We must be in a forced shutdown, or a
       // non-realtime graph that has finished processing. Some later
       // AppendMessage will detect that the graph has been emptied, and
       // delete it.
@@ -1670,17 +1704,17 @@ public:
   }
 };
 
 } // namespace
 
 void
 MediaStreamGraphImpl::RunInStableState(bool aSourceIsMSG)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Must be called on main thread");
+  MOZ_ASSERT(NS_IsMainThread(), "Must be called on main thread");
 
   nsTArray<nsCOMPtr<nsIRunnable> > runnables;
   // When we're doing a forced shutdown, pending control messages may be
   // run on the main thread via RunDuringShutdown. Those messages must
   // run without the graph monitor being held. So, we collect them here.
   nsTArray<UniquePtr<ControlMessage>> controlMessagesToRunDuringShutdown;
 
   {
@@ -1835,28 +1869,29 @@ MediaStreamGraphImpl::RunInStableState(b
     runnables[i]->Run();
   }
 }
 
 
 void
 MediaStreamGraphImpl::EnsureRunInStableState()
 {
-  NS_ASSERTION(NS_IsMainThread(), "main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "main thread only");
 
   if (mPostedRunInStableState)
     return;
   mPostedRunInStableState = true;
   nsCOMPtr<nsIRunnable> event = new MediaStreamGraphStableStateRunnable(this, false);
   nsContentUtils::RunInStableState(event.forget());
 }
 
 void
 MediaStreamGraphImpl::EnsureStableStateEventPosted()
 {
+  MOZ_ASSERT(OnGraphThread());
   mMonitor.AssertCurrentThreadOwns();
 
   if (mPostedRunInStableStateEvent)
     return;
   mPostedRunInStableStateEvent = true;
   nsCOMPtr<nsIRunnable> event = new MediaStreamGraphStableStateRunnable(this, true);
   mAbstractMainThread->Dispatch(event.forget());
 }
@@ -3521,30 +3556,30 @@ uint32_t WindowToHash(nsPIDOMWindowInner
   hashkey = AddToHash(hashkey, aWindow);
 
   return hashkey;
 }
 
 MediaStreamGraph*
 MediaStreamGraph::GetInstanceIfExists(nsPIDOMWindowInner* aWindow)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 
   uint32_t hashkey = WindowToHash(aWindow);
 
   MediaStreamGraphImpl* graph = nullptr;
   gGraphs.Get(hashkey, &graph);
   return graph;
 }
 
 MediaStreamGraph*
 MediaStreamGraph::GetInstance(MediaStreamGraph::GraphDriverType aGraphDriverRequested,
                               nsPIDOMWindowInner* aWindow)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 
   MediaStreamGraphImpl* graph =
     static_cast<MediaStreamGraphImpl*>(GetInstanceIfExists(aWindow));
 
   if (!graph) {
     if (!gMediaStreamGraphShutdownBlocker) {
 
       class Blocker : public media::ShutdownBlocker
@@ -3601,33 +3636,33 @@ MediaStreamGraph::GetInstance(MediaStrea
 
   return graph;
 }
 
 MediaStreamGraph*
 MediaStreamGraph::CreateNonRealtimeInstance(TrackRate aSampleRate,
                                             nsPIDOMWindowInner* aWindow)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
 
   nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(aWindow);
   MediaStreamGraphImpl* graph = new MediaStreamGraphImpl(
     OFFLINE_THREAD_DRIVER,
     aSampleRate,
     parentObject->AbstractMainThreadFor(TaskCategory::Other));
 
   LOG(LogLevel::Debug, ("Starting up Offline MediaStreamGraph %p", graph));
 
   return graph;
 }
 
 void
 MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
 {
-  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "Main thread only");
   MOZ_ASSERT(aGraph->IsNonRealtime(), "Should not destroy the global graph here");
 
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
 
   if (!graph->mNonRealtimeProcessing) {
     // Start the graph, but don't produce anything
     graph->StartNonRealtimeProcessing(0);
   }
@@ -3636,16 +3671,17 @@ MediaStreamGraph::DestroyNonRealtimeInst
 
 NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter, nsITimerCallback,
                   nsINamed)
 
 NS_IMETHODIMP
 MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,
                                      nsISupports* aData, bool aAnonymize)
 {
+  MOZ_ASSERT(NS_IsMainThread());
   if (mLifecycleState >= LIFECYCLE_WAITING_FOR_THREAD_SHUTDOWN) {
     // Shutting down, nothing to report.
     FinishCollectReports(aHandleReport, aData, nsTArray<AudioNodeSizes>());
     return NS_OK;
   }
 
   class Message final : public ControlMessage {
   public:
@@ -3873,28 +3909,30 @@ MediaStreamGraph::NotifyWhenGraphStarted
     MediaStreamGraphImpl* graphImpl = static_cast<MediaStreamGraphImpl*>(this);
     graphImpl->AppendMessage(MakeUnique<GraphStartedNotificationControlMessage>(aStream));
   }
 }
 
 void
 MediaStreamGraphImpl::IncrementSuspendCount(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   if (!aStream->IsSuspended()) {
     MOZ_ASSERT(mStreams.Contains(aStream));
     mStreams.RemoveElement(aStream);
     mSuspendedStreams.AppendElement(aStream);
     SetStreamOrderDirty();
   }
   aStream->IncrementSuspendCount();
 }
 
 void
 MediaStreamGraphImpl::DecrementSuspendCount(MediaStream* aStream)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   bool wasSuspended = aStream->IsSuspended();
   aStream->DecrementSuspendCount();
   if (wasSuspended && !aStream->IsSuspended()) {
     MOZ_ASSERT(mSuspendedStreams.Contains(aStream));
     mSuspendedStreams.RemoveElement(aStream);
     mStreams.AppendElement(aStream);
     ProcessedMediaStream* ps = aStream->AsProcessedStream();
     if (ps) {
@@ -3903,16 +3941,17 @@ MediaStreamGraphImpl::DecrementSuspendCo
     SetStreamOrderDirty();
   }
 }
 
 void
 MediaStreamGraphImpl::SuspendOrResumeStreams(AudioContextOperation aAudioContextOperation,
                                              const nsTArray<MediaStream*>& aStreamSet)
 {
+  MOZ_ASSERT(OnGraphThreadOrNotRunning());
   // For our purpose, Suspend and Close are equivalent: we want to remove the
   // streams from the set of streams that are going to be processed.
   for (MediaStream* stream : aStreamSet) {
     if (aAudioContextOperation == AudioContextOperation::Resume) {
       DecrementSuspendCount(stream);
     } else {
       IncrementSuspendCount(stream);
     }
@@ -3963,17 +4002,17 @@ MediaStreamGraphImpl::AudioContextOperat
   mAbstractMainThread->Dispatch(event.forget());
 }
 
 void
 MediaStreamGraphImpl::ApplyAudioContextOperationImpl(
     MediaStream* aDestinationStream, const nsTArray<MediaStream*>& aStreams,
     AudioContextOperation aOperation, void* aPromise)
 {
-  MOZ_ASSERT(CurrentDriver()->OnThread());
+  MOZ_ASSERT(OnGraphThread());
 
   SuspendOrResumeStreams(aOperation, aStreams);
 
   bool switching = false;
   GraphDriver* nextDriver = nullptr;
   {
     MonitorAutoLock lock(mMonitor);
     switching = CurrentDriver()->Switching();
@@ -4106,17 +4145,17 @@ bool
 MediaStreamGraph::IsNonRealtime() const
 {
   return !static_cast<const MediaStreamGraphImpl*>(this)->mRealtime;
 }
 
 void
 MediaStreamGraph::StartNonRealtimeProcessing(uint32_t aTicksToProcess)
 {
-  NS_ASSERTION(NS_IsMainThread(), "main thread only");
+  MOZ_ASSERT(NS_IsMainThread(), "main thread only");
 
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
   NS_ASSERTION(!graph->mRealtime, "non-realtime only");
 
   if (graph->mNonRealtimeProcessing)
     return;
 
   graph->mEndTime =
--- a/dom/media/MediaStreamGraph.h
+++ b/dom/media/MediaStreamGraph.h
@@ -1388,16 +1388,17 @@ protected:
   virtual ~MediaStreamGraph()
   {
     MOZ_COUNT_DTOR(MediaStreamGraph);
   }
 
   // Intended only for assertions, either on graph thread or not running (in
   // which case we must be on the main thread).
   bool OnGraphThreadOrNotRunning() const;
+  bool OnGraphThread() const;
 
   // Media graph thread only
   nsTArray<nsCOMPtr<nsIRunnable> > mPendingUpdateRunnables;
 
   /**
    * Sample rate at which this graph runs. For real time graphs, this is
    * the rate of the audio mixer. For offline graphs, this is the rate specified
    * at construction.
--- a/dom/media/MediaStreamGraphImpl.h
+++ b/dom/media/MediaStreamGraphImpl.h
@@ -412,16 +412,17 @@ public:
    * Remove aPort from the graph and release it.
    */
   void DestroyPort(MediaInputPort* aPort);
   /**
    * Mark the media stream order as dirty.
    */
   void SetStreamOrderDirty()
   {
+    MOZ_ASSERT(OnGraphThreadOrNotRunning());
     mStreamOrderDirty = true;
   }
 
   uint32_t AudioChannelCount() const
   {
     return mOutputChannels;
   }