Bug 1221587: patch 13: Clear SharedThreadPool before shutdown-threads, and don't switch from SystemClockDriver to SystemClockDriver r=padenot draft
authorRandell Jesup <rjesup@jesup.org>
Tue, 12 Jan 2016 18:14:14 -0500
changeset 321208 8a720f2787051ed7f5b410697501a4df711e65df
parent 321207 02d45031c30087461717ffea189dbcb8dbcfffbd
child 512873 fa2462990fd6ac8d5e6edaeee04b646b0178d99a
push id9349
push userrjesup@wgate.com
push dateWed, 13 Jan 2016 06:48:48 +0000
reviewerspadenot
bugs1221587
milestone46.0a1
Bug 1221587: patch 13: Clear SharedThreadPool before shutdown-threads, and don't switch from SystemClockDriver to SystemClockDriver r=padenot
dom/media/GraphDriver.cpp
dom/media/MediaStreamGraph.cpp
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -476,22 +476,25 @@ AsyncCubebTask::~AsyncCubebTask()
 /* static */
 nsresult
 AsyncCubebTask::EnsureThread()
 {
   if (!sThreadPool) {
     nsCOMPtr<nsIThreadPool> threadPool =
       SharedThreadPool::Get(NS_LITERAL_CSTRING("CubebOperation"), 1);
     sThreadPool = threadPool;
+    // Need to null this out before xpcom-shutdown-threads Observers run
+    // since we don't know the order that the shutdown-threads observers
+    // will run.  ClearOnShutdown guarantees it runs first.
     if (!NS_IsMainThread()) {
       NS_DispatchToMainThread(NS_NewRunnableFunction([]() -> void {
-        ClearOnShutdown(&sThreadPool);
+            ClearOnShutdown(&sThreadPool, ShutdownPhase::ShutdownThreads);
       }));
     } else {
-      ClearOnShutdown(&sThreadPool);
+      ClearOnShutdown(&sThreadPool, ShutdownPhase::ShutdownThreads);
     }
 
     const uint32_t kIdleThreadTimeoutMs = 2000;
 
     nsresult rv = sThreadPool->SetIdleThreadTimeout(PR_MillisecondsToInterval(kIdleThreadTimeoutMs));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -344,16 +344,18 @@ MediaStreamGraphImpl::UpdateStreamOrder(
       audioTrackPresent = true;
     } else {
       for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer(), MediaSegment::AUDIO);
            !tracks.IsEnded(); tracks.Next()) {
         audioTrackPresent = true;
       }
     }
   }
+  // Note that this looks for any audio streams, input or output, and switches to a
+  // SystemClockDriver if there are none
 
   if (!audioTrackPresent && mRealtime &&
       CurrentDriver()->AsAudioCallbackDriver()) {
     MonitorAutoLock mon(mMonitor);
     if (CurrentDriver()->AsAudioCallbackDriver()->IsStarted()) {
       if (mLifecycleState == LIFECYCLE_RUNNING) {
         SystemClockDriver* driver = new SystemClockDriver(this);
         CurrentDriver()->SwitchAtNextIteration(driver);
@@ -985,17 +987,18 @@ MediaStreamGraphImpl::CloseAudioInputImp
 
   // Switch Drivers since we're adding or removing an input (to nothing/system or output only)
   bool audioTrackPresent = false;
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaStream* stream = mStreams[i];
     // If this is a AudioNodeStream, force a AudioCallbackDriver.
     if (stream->AsAudioNodeStream()) {
       audioTrackPresent = true;
-    } else {
+    } else if (CurrentDriver()->AsAudioCallbackDriver()) {
+      // only if there's a real switch!
       for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer(), MediaSegment::AUDIO);
            !tracks.IsEnded(); tracks.Next()) {
         audioTrackPresent = true;
       }
     }
   }
 
   MonitorAutoLock mon(mMonitor);