Bug 1340665 - Fix warnings on shutdown. r=billm draft
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 10 Mar 2017 17:55:35 -0800
changeset 496985 7435440f35a5166aead4129c59f7f0315d32d1d1
parent 494872 58753259bfeb3b818eac7870871b0aae1f8de64a
child 548777 f0db5fa0677eef2aecdb13c5177e3e6d3310f196
push id48771
push userbmo:mrbkap@mozilla.com
push dateSat, 11 Mar 2017 01:57:15 +0000
reviewersbillm
bugs1340665
milestone55.0a1
Bug 1340665 - Fix warnings on shutdown. r=billm The code to make a ValidatingDispatcher break cycles when we're done with it assumes that XPCOM is still up and running. This isn't the case during shutdown. When XPCOM shuts down, we should avoid do_GetMainThread. MozReview-Commit-ID: 5Gpko9FbFxl
dom/base/TabGroup.cpp
xpcom/threads/Dispatcher.cpp
xpcom/threads/Dispatcher.h
xpcom/threads/SystemGroup.cpp
--- a/dom/base/TabGroup.cpp
+++ b/dom/base/TabGroup.cpp
@@ -162,17 +162,17 @@ TabGroup::Leave(nsPIDOMWindowOuter* aWin
   MOZ_ASSERT(mWindows.Contains(aWindow));
   mWindows.RemoveElement(aWindow);
 
   // The Chrome TabGroup doesn't have cyclical references through mEventTargets
   // to itself, meaning that we don't have to worry about nulling mEventTargets
   // out after the last window leaves.
   if (!mIsChrome && mWindows.IsEmpty()) {
     mLastWindowLeft = true;
-    Shutdown();
+    Shutdown(false);
   }
 }
 
 nsresult
 TabGroup::FindItemWithName(const nsAString& aName,
                            nsIDocShellTreeItem* aRequestor,
                            nsIDocShellTreeItem* aOriginalRequestor,
                            nsIDocShellTreeItem** aFoundItem)
--- a/xpcom/threads/Dispatcher.cpp
+++ b/xpcom/threads/Dispatcher.cpp
@@ -147,24 +147,26 @@ ValidatingDispatcher::Dispatch(const cha
 {
   return LabeledDispatch(aName, aCategory, Move(aRunnable));
 }
 
 nsIEventTarget*
 ValidatingDispatcher::EventTargetFor(TaskCategory aCategory) const
 {
   MOZ_ASSERT(aCategory != TaskCategory::Count);
+  MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
   return mEventTargets[size_t(aCategory)];
 }
 
 AbstractThread*
 ValidatingDispatcher::AbstractMainThreadForImpl(TaskCategory aCategory)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aCategory != TaskCategory::Count);
+  MOZ_ASSERT(mEventTargets[size_t(aCategory)]);
 
   if (!mAbstractThreads[size_t(aCategory)]) {
     mAbstractThreads[size_t(aCategory)] =
       AbstractThread::CreateEventTargetWrapper(mEventTargets[size_t(aCategory)],
                                                /* aDrainDirectTasks = */ true);
   }
 
   return mAbstractThreads[size_t(aCategory)];
@@ -182,24 +184,24 @@ ValidatingDispatcher::CreateEventTargets
       mEventTargets[i] = do_GetMainThread();
     } else {
       mEventTargets[i] = CreateEventTargetFor(category);
     }
   }
 }
 
 void
-ValidatingDispatcher::Shutdown()
+ValidatingDispatcher::Shutdown(bool aXPCOMShutdown)
 {
   // There is a RefPtr cycle TabGroup -> DispatcherEventTarget -> TabGroup. To
   // avoid leaks, we need to break the chain somewhere. We shouldn't be using
   // the ThrottledEventQueue for this TabGroup when no windows belong to it,
   // so it's safe to null out the queue here.
   for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
-    mEventTargets[i] = do_GetMainThread();
+    mEventTargets[i] = aXPCOMShutdown ? nullptr : do_GetMainThread();
     mAbstractThreads[i] = nullptr;
   }
 }
 
 already_AddRefed<nsIEventTarget>
 ValidatingDispatcher::CreateEventTargetFor(TaskCategory aCategory)
 {
   RefPtr<DispatcherEventTarget> target =
--- a/xpcom/threads/Dispatcher.h
+++ b/xpcom/threads/Dispatcher.h
@@ -107,17 +107,20 @@ protected:
   // function returns |dispatcher|.
   static ValidatingDispatcher* FromEventTarget(nsIEventTarget* aEventTarget);
 
   nsresult LabeledDispatch(const char* aName,
                            TaskCategory aCategory,
                            already_AddRefed<nsIRunnable>&& aRunnable);
 
   void CreateEventTargets(bool aNeedValidation);
-  void Shutdown();
+
+  // Shuts down this dispatcher. If aXPCOMShutdown is true, invalidates this
+  // dispatcher.
+  void Shutdown(bool aXPCOMShutdown);
 
   enum ValidationType {
     StartValidation,
     EndValidation,
   };
   void SetValidatingAccess(ValidationType aType);
 
   static ValidatingDispatcher* sRunningDispatcher;
--- a/xpcom/threads/SystemGroup.cpp
+++ b/xpcom/threads/SystemGroup.cpp
@@ -48,17 +48,17 @@ SystemGroupImpl::InitStatic()
   MOZ_ASSERT(!sSingleton);
   MOZ_ASSERT(NS_IsMainThread());
   sSingleton = MakeUnique<SystemGroupImpl>();
 }
 
 /* static */ void
 SystemGroupImpl::ShutdownStatic()
 {
-  sSingleton->Shutdown();
+  sSingleton->Shutdown(true);
   sSingleton = nullptr;
 }
 
 /* static */ SystemGroupImpl*
 SystemGroupImpl::Get()
 {
   MOZ_ASSERT(sSingleton);
   return sSingleton.get();