Bug 1460346 - Fix a case that ThreadedDriver is started when it is already working. r?padenot draft
authorAlex Chronopoulos <achronop@gmail.com>
Fri, 25 May 2018 11:58:58 +0300
changeset 812360 aaa60b3b52a87a4e3be0b9e222d70cce9454b62c
parent 812359 ba87df49401778c7a39eb52496dcd33cfe1f7028
child 812361 ad44da5d5e1545beafed8e3553ebc1a50fda567c
push id114537
push userachronop@gmail.com
push dateFri, 29 Jun 2018 08:25:16 +0000
reviewerspadenot
bugs1460346
milestone63.0a1
Bug 1460346 - Fix a case that ThreadedDriver is started when it is already working. r?padenot MozReview-Commit-ID: 6R6WH3ITw03
dom/media/GraphDriver.cpp
dom/media/GraphDriver.h
dom/media/MediaStreamGraph.cpp
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -226,26 +226,26 @@ public:
   }
 private:
   RefPtr<ThreadedDriver> mDriver;
 };
 
 void
 ThreadedDriver::Start()
 {
-  LOG(LogLevel::Debug,
-      ("Starting thread for a SystemClockDriver  %p", mGraphImpl));
+  MOZ_ASSERT(!ThreadRunning());
+  LOG(LogLevel::Debug, ("Starting thread for a SystemClockDriver  %p", mGraphImpl));
   Unused << NS_WARN_IF(mThread);
-  if (!mThread) { // Ensure we haven't already started it
-    nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
-    // Note: mThread may be null during event->Run() if we pass to NewNamedThread!  See AudioInitTask
-    nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
-    if (NS_SUCCEEDED(rv)) {
-      mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
-    }
+  MOZ_ASSERT(!mThread); // Ensure we haven't already started it
+
+  nsCOMPtr<nsIRunnable> event = new MediaStreamGraphInitThreadRunnable(this);
+  // Note: mThread may be null during event->Run() if we pass to NewNamedThread!  See AudioInitTask
+  nsresult rv = NS_NewNamedThread("MediaStreamGrph", getter_AddRefs(mThread));
+  if (NS_SUCCEEDED(rv)) {
+    mThread->EventTarget()->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
   }
 }
 
 void
 ThreadedDriver::Revive()
 {
   MOZ_ASSERT(NS_IsMainThread() && !ThreadRunning());
   // Note: only called on MainThread, without monitor
--- a/dom/media/GraphDriver.h
+++ b/dom/media/GraphDriver.h
@@ -116,17 +116,19 @@ public:
   explicit GraphDriver(MediaStreamGraphImpl* aGraphImpl);
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GraphDriver);
   /* For real-time graphs, this waits until it's time to process more data. For
    * offline graphs, this is a no-op. */
   virtual void WaitForNextIteration() = 0;
   /* Wakes up the graph if it is waiting. */
   virtual void WakeUp() = 0;
-  /* Start the graph, init the driver, start the thread. */
+  /* Start the graph, init the driver, start the thread.
+   * A driver cannot be started twice, it must be shutdown
+   * before being started again. */
   virtual void Start() = 0;
   /* Revive this driver, as more messages just arrived. */
   virtual void Revive() = 0;
   /* Shutdown GraphDriver (synchronously) */
   virtual void Shutdown() = 0;
   /* Rate at which the GraphDriver runs, in ms. This can either be user
    * controlled (because we are using a {System,Offline}ClockDriver, and decide
    * how often we want to wakeup/how much we want to process per iteration), or
--- a/dom/media/MediaStreamGraph.cpp
+++ b/dom/media/MediaStreamGraph.cpp
@@ -1400,17 +1400,21 @@ MediaStreamGraphImpl::ForceShutDown(medi
     NS_NewTimerWithCallback(getter_AddRefs(mShutdownTimer),
                             this,
                             MediaStreamGraph::AUDIO_CALLBACK_DRIVER_SHUTDOWN_TIMEOUT,
                             nsITimer::TYPE_ONE_SHOT);
   }
   mForceShutdownTicket = aShutdownTicket;
   MonitorAutoLock lock(mMonitor);
   mForceShutDown = true;
-  if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED) {
+  if (IsNonRealtime()) {
+    // Start the graph if it has not been started already, but don't produce anything.
+    // This method will return early if the graph is already started.
+    StartNonRealtimeProcessing(0);
+  } else if (LifecycleStateRef() == LIFECYCLE_THREAD_NOT_STARTED) {
     // We *could* have just sent this a message to start up, so don't
     // yank the rug out from under it.  Tell it to startup and let it
     // shut down.
     RefPtr<GraphDriver> driver = CurrentDriver();
     MonitorAutoUnlock unlock(mMonitor);
     driver->Start();
   }
   EnsureNextIterationLocked();
@@ -3777,22 +3781,16 @@ MediaStreamGraph::CreateNonRealtimeInsta
 
 void
 MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
 {
   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);
-  }
-
   graph->ForceShutDown(nullptr);
 }
 
 NS_IMPL_ISUPPORTS(MediaStreamGraphImpl, nsIMemoryReporter, nsITimerCallback,
                   nsINamed)
 
 NS_IMETHODIMP
 MediaStreamGraphImpl::CollectReports(nsIHandleReportCallback* aHandleReport,