Bug 1150687 - Add a convenience/efficiently routine to get an AbstractThread for the main thread. r=jww
authorBobby Holley <bobbyholley@gmail.com>
Thu, 02 Apr 2015 13:21:53 -0700
changeset 267649 042e550395ebdd99add88fe29f47b1f55c560a3f
parent 267648 20fab9c2a8ac46240f2f37d878e81148af09d3dd
child 267650 e8893a7c40cdca6c273fd8ccd4a234da84b49685
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjww
bugs1150687
milestone40.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 1150687 - Add a convenience/efficiently routine to get an AbstractThread for the main thread. r=jww
dom/media/AbstractThread.cpp
dom/media/AbstractThread.h
dom/media/MediaDecoder.cpp
--- a/dom/media/AbstractThread.cpp
+++ b/dom/media/AbstractThread.cpp
@@ -4,18 +4,23 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AbstractThread.h"
 
 #include "MediaTaskQueue.h"
 #include "nsThreadUtils.h"
 
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/StaticPtr.h"
+
 namespace mozilla {
 
+StaticRefPtr<AbstractThread> sMainThread;
+
 template<>
 nsresult
 AbstractThreadImpl<MediaTaskQueue>::Dispatch(already_AddRefed<nsIRunnable> aRunnable)
 {
   RefPtr<nsIRunnable> r(aRunnable);
   return mTarget->ForceDispatch(r);
 }
 
@@ -36,9 +41,29 @@ AbstractThreadImpl<MediaTaskQueue>::IsCu
 
 template<>
 bool
 AbstractThreadImpl<nsIThread>::IsCurrentThreadIn()
 {
   return NS_GetCurrentThread() == mTarget;
 }
 
+AbstractThread*
+AbstractThread::MainThread()
+{
+  MOZ_ASSERT(sMainThread);
+  return sMainThread;
+}
+
+void
+AbstractThread::EnsureMainThreadSingleton()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!sMainThread) {
+    nsCOMPtr<nsIThread> mainThread;
+    NS_GetMainThread(getter_AddRefs(mainThread));
+    MOZ_DIAGNOSTIC_ASSERT(mainThread);
+    sMainThread = AbstractThread::Create(mainThread.get());
+    ClearOnShutdown(&sMainThread);
+  }
+}
+
 } // namespace mozilla
--- a/dom/media/AbstractThread.h
+++ b/dom/media/AbstractThread.h
@@ -31,16 +31,24 @@ namespace mozilla {
 class AbstractThread
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractThread);
   virtual nsresult Dispatch(already_AddRefed<nsIRunnable> aRunnable) = 0;
   virtual bool IsCurrentThreadIn() = 0;
 
   template<typename TargetType> static AbstractThread* Create(TargetType* aTarget);
+
+  // Convenience method for getting an AbstractThread for the main thread.
+  //
+  // EnsureMainThreadSingleton must be called on the main thread before any
+  // other threads that might use MainThread() are spawned.
+  static AbstractThread* MainThread();
+  static void EnsureMainThreadSingleton();
+
 protected:
   virtual ~AbstractThread() {}
 };
 
 template<typename TargetType>
 class AbstractThreadImpl : public AbstractThread
 {
 public:
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -607,16 +607,17 @@ MediaDecoder::MediaDecoder() :
   mHeuristicDormantTimeout(
     Preferences::GetInt("media.decoder.heuristic.dormant.timeout",
                         DEFAULT_HEURISTIC_DORMANT_TIMEOUT_MSECS)),
   mIsHeuristicDormant(false)
 {
   MOZ_COUNT_CTOR(MediaDecoder);
   MOZ_ASSERT(NS_IsMainThread());
   MediaMemoryTracker::AddMediaDecoder(this);
+  AbstractThread::EnsureMainThreadSingleton();
 #ifdef PR_LOGGING
   if (!gMediaDecoderLog) {
     gMediaDecoderLog = PR_NewLogModule("MediaDecoder");
   }
 #endif
   mAudioChannel = AudioChannelService::GetDefaultAudioChannel();
 }