Bug 1245789 - Make XPCOMThreadWrapper::GetCurrent() work. r=bholley
authorChris Pearce <cpearce@mozilla.com>
Tue, 12 Apr 2016 16:12:22 +1200
changeset 330617 5d1fbbad622c81ca0d1fee3964b1f3aa63213bc8
parent 330616 0b9c34023af8201c6623877db40e14fc1deafda2
child 330618 58d63f3f7e10673aa9a921a6978777e267f31f63
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1245789
milestone48.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 1245789 - Make XPCOMThreadWrapper::GetCurrent() work. r=bholley XPCOMThreadWrapper::GetCurrent() is failing because it's not keeping AbstractThread::sCurrentThreadTLS up to date. This causes assertion failures during startup of the GMP stack when dispatching via InvokeAsync to the GMP thread, which is an XPCOM thread wrapped by the XPCOMThreadWrapper. We can trivially initialize AbstractThread::sCurrentThreadTLS to be the XPCOMThreadWrapper on the target thread, since it's thread-local-storage, and the target thread won't change. MozReview-Commit-ID: EIEFZppR2PS
dom/media/gmp/GMPService.cpp
xpcom/threads/AbstractThread.cpp
xpcom/threads/AbstractThread.h
--- a/dom/media/gmp/GMPService.cpp
+++ b/dom/media/gmp/GMPService.cpp
@@ -352,17 +352,17 @@ GeckoMediaPluginService::GetThread(nsITh
       return NS_ERROR_FAILURE;
     }
 
     nsresult rv = NS_NewNamedThread("GMPThread", getter_AddRefs(mGMPThread));
     if (NS_FAILED(rv)) {
       return rv;
     }
 
-    mAbstractGMPThread = CreateXPCOMAbstractThreadWrapper(mGMPThread, false);
+    mAbstractGMPThread = AbstractThread::CreateXPCOMThreadWrapper(mGMPThread, false);
 
     // Tell the thread to initialize plugins
     InitializePlugins();
   }
 
   nsCOMPtr<nsIThread> copy = mGMPThread;
   copy.forget(aThread);
 
--- a/xpcom/threads/AbstractThread.cpp
+++ b/xpcom/threads/AbstractThread.cpp
@@ -141,16 +141,23 @@ AbstractThread::DispatchStateChange(alre
 }
 
 /* static */ void
 AbstractThread::DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable)
 {
   GetCurrent()->TailDispatcher().AddDirectTask(Move(aRunnable));
 }
 
+/* static */
 already_AddRefed<AbstractThread>
-CreateXPCOMAbstractThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch)
+AbstractThread::CreateXPCOMThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch)
 {
   RefPtr<XPCOMThreadWrapper> wrapper = new XPCOMThreadWrapper(aThread, aRequireTailDispatch);
+  // Set the thread-local sCurrentThreadTLS to point to the wrapper on the
+  // target thread. This ensures that sCurrentThreadTLS is as expected by
+  // AbstractThread::GetCurrent() on the target thread.
+  nsCOMPtr<nsIRunnable> r =
+    NS_NewRunnableFunction([wrapper]() { sCurrentThreadTLS.set(wrapper); });
+  aThread->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
   return wrapper.forget();
 }
 
 } // namespace mozilla
--- a/xpcom/threads/AbstractThread.h
+++ b/xpcom/threads/AbstractThread.h
@@ -37,16 +37,19 @@ class AbstractThread
 {
 public:
   // Returns the AbstractThread that the caller is currently running in, or null
   // if the caller is not running in an AbstractThread.
   static AbstractThread* GetCurrent() { return sCurrentThreadTLS.get(); }
 
   AbstractThread(bool aSupportsTailDispatch) : mSupportsTailDispatch(aSupportsTailDispatch) {}
 
+  static already_AddRefed<AbstractThread>
+  CreateXPCOMThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch);
+
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AbstractThread);
 
   enum DispatchFailureHandling { AssertDispatchSuccess, DontAssertDispatchSuccess };
   enum DispatchReason { NormalDispatch, TailDispatch };
   virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
                         DispatchFailureHandling aHandling = AssertDispatchSuccess,
                         DispatchReason aReason = NormalDispatch) = 0;
 
@@ -87,14 +90,11 @@ protected:
   virtual ~AbstractThread() {}
   static MOZ_THREAD_LOCAL(AbstractThread*) sCurrentThreadTLS;
 
   // True if we want to require that every task dispatched from tasks running in
   // this queue go through our queue's tail dispatcher.
   const bool mSupportsTailDispatch;
 };
 
-already_AddRefed<AbstractThread> CreateXPCOMAbstractThreadWrapper(nsIThread* aThread,
-                                 bool aRequireTailDispatch);
-
 } // namespace mozilla
 
 #endif