Bug 848954 - Part 18 - Start the thread after having processed the messages to make sure there are messages in the queue when processing starts. r=roc
authorPaul Adenot <paul@paul.cx>
Tue, 26 Aug 2014 17:02:09 +0200
changeset 223508 f8bb3bcc38eb767620d7ba19decb1c0f173e4cb3
parent 223507 b5b970976871929ace2490a57b91a4f50b9d5667
child 223509 256f26db10f176dbac842fbabeb8f7a84786fe3e
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs848954
milestone34.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 848954 - Part 18 - Start the thread after having processed the messages to make sure there are messages in the queue when processing starts. r=roc
content/media/GraphDriver.cpp
content/media/MediaStreamGraph.cpp
--- a/content/media/GraphDriver.cpp
+++ b/content/media/GraphDriver.cpp
@@ -167,27 +167,27 @@ public:
     : mDriver(aDriver)
   {
   }
   NS_IMETHOD Run()
   {
     char aLocal;
     STREAM_LOG(PR_LOG_DEBUG, ("Starting system thread"));
     profiler_register_thread("MediaStreamGraph", &aLocal);
-    {
-      MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
-      mDriver->mGraphImpl->SwapMessageQueues();
-    }
     if (mDriver->mPreviousDriver) {
       MOZ_ASSERT(!mDriver->AsAudioCallbackDriver());
       // Stop and release the previous driver off-main-thread.
       nsRefPtr<AsyncCubebTask> releaseEvent =
         new AsyncCubebTask(mDriver->mPreviousDriver->AsAudioCallbackDriver(), AsyncCubebTask::SHUTDOWN);
       mDriver->mPreviousDriver = nullptr;
       releaseEvent->Dispatch();
+    } else {
+      MonitorAutoLock mon(mDriver->mGraphImpl->GetMonitor());
+      MOZ_ASSERT(mDriver->mGraphImpl->MessagesQueued(), "Don't start a graph without messages queued.");
+      mDriver->mGraphImpl->SwapMessageQueues();
     }
     mDriver->RunThread();
     return NS_OK;
   }
 private:
   ThreadedDriver* mDriver;
 };
 
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -1559,36 +1559,16 @@ MediaStreamGraphImpl::RunInStableState()
     for (uint32_t i = 0; i < mStreamUpdates.Length(); ++i) {
       StreamUpdate* update = &mStreamUpdates[i];
       if (update->mStream) {
         ApplyStreamUpdate(update);
       }
     }
     mStreamUpdates.Clear();
 
-    // Don't start the thread for a non-realtime graph until it has been
-    // explicitly started by StartNonRealtimeProcessing.
-    if (mLifecycleState == LIFECYCLE_THREAD_NOT_STARTED &&
-        (mRealtime || mNonRealtimeProcessing)) {
-      mLifecycleState = LIFECYCLE_RUNNING;
-      // Start the thread now. We couldn't start it earlier because
-      // the graph might exit immediately on finding it has no streams. The
-      // first message for a new graph must create a stream.
-      {
-        // We should exit the monitor for now, because starting a stream might
-        // take locks, and we don't want to deadlock. We probably want this to be
-        // async on another thread.
-        MonitorAutoUnlock unlock(mMonitor);
-        STREAM_LOG(PR_LOG_DEBUG, ("Starting a graph with a %s\n",
-              CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" :
-                                                         "SystemDriver"));
-        CurrentDriver()->Start();
-      }
-    }
-
     if (mCurrentTaskMessageQueue.IsEmpty()) {
       if (mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP && IsEmpty()) {
         // Complete shutdown. First, ensure that this graph is no longer used.
         // A new graph graph will be created if one is needed.
         STREAM_LOG(PR_LOG_DEBUG, ("Disconnecting MediaStreamGraph %p", this));
         if (this == gGraph) {
           // null out gGraph if that's the graph being shut down
           gGraph = nullptr;
@@ -1621,16 +1601,33 @@ MediaStreamGraphImpl::RunInStableState()
         // or it might exit immediately.
         {
           MonitorAutoUnlock unlock(mMonitor);
           CurrentDriver()->Revive();
         }
       }
     }
 
+    // Don't start the thread for a non-realtime graph until it has been
+    // explicitly started by StartNonRealtimeProcessing.
+    if (mLifecycleState == LIFECYCLE_THREAD_NOT_STARTED &&
+        (mRealtime || mNonRealtimeProcessing)) {
+      mLifecycleState = LIFECYCLE_RUNNING;
+      // Start the thread now. We couldn't start it earlier because
+      // the graph might exit immediately on finding it has no streams. The
+      // first message for a new graph must create a stream.
+      {
+        // We should exit the monitor for now, because starting a stream might
+        // take locks, and we don't want to deadlock.
+        MonitorAutoUnlock unlock(mMonitor);
+        STREAM_LOG(PR_LOG_DEBUG, ("Starting a graph ! %s\n", CurrentDriver()->AsAudioCallbackDriver() ? "AudioDriver" : "SystemDriver"));
+        CurrentDriver()->Start();
+      }
+    }
+
     if ((mForceShutDown || !mRealtime) &&
         mLifecycleState == LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP) {
       // Defer calls to RunDuringShutdown() to happen while mMonitor is not held.
       for (uint32_t i = 0; i < mBackMessageQueue.Length(); ++i) {
         MessageBlock& mb = mBackMessageQueue[i];
         controlMessagesToRunDuringShutdown.MoveElementsFrom(mb.mMessages);
       }
       mBackMessageQueue.Clear();