Bug 1300118 P3 Fix TaskQueue sCurrentThread TLS handling for nsIEventTarget targets. r=jwwang
authorBen Kelly <ben@wanderview.com>
Mon, 12 Sep 2016 11:21:01 -0700
changeset 313574 0393ff1b2645b623ec3cd750d18d7b7ded75f0b1
parent 313573 4b66e6bb1db83dca773b01c9bcb35c2f93ef712b
child 313575 fba3a9f229cff78338c8c647012cd5921c6acd86
push id30694
push usercbook@mozilla.com
push dateTue, 13 Sep 2016 09:58:08 +0000
treeherdermozilla-central@f5d043ce6d36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwwang
bugs1300118
milestone51.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 1300118 P3 Fix TaskQueue sCurrentThread TLS handling for nsIEventTarget targets. r=jwwang
xpcom/threads/AbstractThread.cpp
xpcom/threads/TaskQueue.cpp
xpcom/threads/TaskQueue.h
--- a/xpcom/threads/AbstractThread.cpp
+++ b/xpcom/threads/AbstractThread.cpp
@@ -65,17 +65,16 @@ public:
 
   virtual bool IsCurrentThreadIn() override
   {
     // Compare NSPR threads so that this works after shutdown when
     // NS_GetCurrentThread starts returning null.
     PRThread* thread = nullptr;
     mTarget->GetPRThread(&thread);
     bool in = PR_GetCurrentThread() == thread;
-    MOZ_ASSERT(in == (GetCurrent() == this));
     return in;
   }
 
   void FireTailDispatcher()
   {
     MOZ_DIAGNOSTIC_ASSERT(mTailDispatcher.isSome());
     mTailDispatcher.ref().DrainDirectTasks();
     mTailDispatcher.reset();
--- a/xpcom/threads/TaskQueue.cpp
+++ b/xpcom/threads/TaskQueue.cpp
@@ -186,17 +186,16 @@ TaskQueue::IsEmpty()
   MonitorAutoLock mon(mQueueMonitor);
   return mTasks.empty();
 }
 
 bool
 TaskQueue::IsCurrentThreadIn()
 {
   bool in = NS_GetCurrentThread() == mRunningThread;
-  MOZ_ASSERT(in == (GetCurrent() == this));
   return in;
 }
 
 already_AddRefed<nsIEventTarget>
 TaskQueue::WrapAsEventTarget()
 {
   nsCOMPtr<nsIEventTarget> ref = new EventTargetWrapper(this);
   return ref.forget();
--- a/xpcom/threads/TaskQueue.h
+++ b/xpcom/threads/TaskQueue.h
@@ -143,42 +143,44 @@ protected:
   Atomic<nsIThread*> mRunningThread;
 
   // RAII class that gets instantiated for each dispatched task.
   class AutoTaskGuard : public AutoTaskDispatcher
   {
   public:
     explicit AutoTaskGuard(TaskQueue* aQueue)
       : AutoTaskDispatcher(/* aIsTailDispatcher = */ true), mQueue(aQueue)
+      , mLastCurrentThread(nullptr)
     {
       // NB: We don't hold the lock to aQueue here. Don't do anything that
       // might require it.
       MOZ_ASSERT(!mQueue->mTailDispatcher);
       mQueue->mTailDispatcher = this;
 
-      MOZ_ASSERT(sCurrentThreadTLS.get() == nullptr);
+      mLastCurrentThread = sCurrentThreadTLS.get();
       sCurrentThreadTLS.set(aQueue);
 
       MOZ_ASSERT(mQueue->mRunningThread == nullptr);
       mQueue->mRunningThread = NS_GetCurrentThread();
     }
 
     ~AutoTaskGuard()
     {
       DrainDirectTasks();
 
       MOZ_ASSERT(mQueue->mRunningThread == NS_GetCurrentThread());
       mQueue->mRunningThread = nullptr;
 
-      sCurrentThreadTLS.set(nullptr);
+      sCurrentThreadTLS.set(mLastCurrentThread);
       mQueue->mTailDispatcher = nullptr;
     }
 
   private:
   TaskQueue* mQueue;
+  AbstractThread* mLastCurrentThread;
   };
 
   TaskDispatcher* mTailDispatcher;
 
   // True if we've dispatched an event to the target to execute events from
   // the queue.
   bool mIsRunning;