Bug 1300118 P3 Fix TaskQueue sCurrentThread TLS handling for nsIEventTarget targets. r=jwwang
authorBen Kelly <ben@wanderview.com>
Tue, 13 Sep 2016 20:12:15 -0700
changeset 313862 e72b06de40c005266f3fed08331eaf7141051a60
parent 313861 4844015b5fb76e47518cda47c7eb36188bd9df37
child 313863 8a8e26a6969040ec85bd9934e5fdf42db55031f6
push id32264
push usercbook@mozilla.com
push dateWed, 14 Sep 2016 10:18:20 +0000
treeherderautoland@b9c4a0402a0a [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;