Bug 1332790 - Don't assert mLastWindowLeft in ~TabGroup when destroying the chrome TabGroup. r=billm, a=lizzard
authorMichael Layzell <michael@thelayzells.com>
Tue, 31 Jan 2017 11:08:35 -0500
changeset 375881 e1922d72c141d45ab42b2d09d6907433a088c9b4
parent 375880 ba5398b3f6fc925b72174fa5740c620a56f21f46
child 375882 7836b720028c78161d182b69ee6155e50dffee8f
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, lizzard
bugs1332790
milestone53.0a2
Bug 1332790 - Don't assert mLastWindowLeft in ~TabGroup when destroying the chrome TabGroup. r=billm, a=lizzard MozReview-Commit-ID: 33C5lF31HDI
dom/base/TabGroup.cpp
dom/base/TabGroup.h
--- a/dom/base/TabGroup.cpp
+++ b/dom/base/TabGroup.cpp
@@ -21,16 +21,17 @@
 namespace mozilla {
 namespace dom {
 
 static StaticRefPtr<TabGroup> sChromeTabGroup;
 
 TabGroup::TabGroup(bool aIsChrome)
  : mLastWindowLeft(false)
  , mThrottledQueuesInitialized(false)
+ , mIsChrome(aIsChrome)
 {
   for (size_t i = 0; i < size_t(TaskCategory::Count); i++) {
     TaskCategory category = static_cast<TaskCategory>(i);
     if (aIsChrome) {
       // The chrome TabGroup dispatches directly to the main thread. This means
       // that we don't have to worry about cyclical references when cleaning up
       // the chrome TabGroup.
       mEventTargets[i] = do_GetMainThread();
@@ -54,17 +55,17 @@ TabGroup::TabGroup(bool aIsChrome)
     EnsureThrottledEventQueues();
   }
 }
 
 TabGroup::~TabGroup()
 {
   MOZ_ASSERT(mDocGroups.IsEmpty());
   MOZ_ASSERT(mWindows.IsEmpty());
-  MOZ_RELEASE_ASSERT(mLastWindowLeft);
+  MOZ_RELEASE_ASSERT(mLastWindowLeft || mIsChrome);
 }
 
 void
 TabGroup::EnsureThrottledEventQueues()
 {
   if (mThrottledQueuesInitialized) {
     return;
   }
@@ -168,17 +169,17 @@ void
 TabGroup::Leave(nsPIDOMWindowOuter* aWindow)
 {
   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 (sChromeTabGroup != this && mWindows.IsEmpty()) {
+  if (!mIsChrome && mWindows.IsEmpty()) {
     mLastWindowLeft = true;
 
     // 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] = nullptr;
@@ -265,17 +266,17 @@ TabGroup::Dispatch(const char* aName,
   }
 }
 
 nsIEventTarget*
 TabGroup::EventTargetFor(TaskCategory aCategory) const
 {
   MOZ_ASSERT(aCategory != TaskCategory::Count);
   if (aCategory == TaskCategory::Worker || aCategory == TaskCategory::Timer) {
-    MOZ_RELEASE_ASSERT(mThrottledQueuesInitialized || this == sChromeTabGroup);
+    MOZ_RELEASE_ASSERT(mThrottledQueuesInitialized || mIsChrome);
   }
 
   if (NS_WARN_IF(mLastWindowLeft)) {
     // Once we've disconnected everything, we still allow people to
     // dispatch. We'll just go directly to the main thread.
     nsCOMPtr<nsIEventTarget> main = do_GetMainThread();
     return main;
   }
--- a/dom/base/TabGroup.h
+++ b/dom/base/TabGroup.h
@@ -124,20 +124,25 @@ public:
 
   virtual AbstractThread*
   AbstractMainThreadFor(TaskCategory aCategory) override;
 
 private:
   void EnsureThrottledEventQueues();
 
   ~TabGroup();
-  DocGroupMap mDocGroups;
+
+  // Thread-safe members
   Atomic<bool> mLastWindowLeft;
+  Atomic<bool> mThrottledQueuesInitialized;
+  const bool mIsChrome;
+
+  // Main thread only
+  DocGroupMap mDocGroups;
   nsTArray<nsPIDOMWindowOuter*> mWindows;
-  Atomic<bool> mThrottledQueuesInitialized;
   nsCOMPtr<nsIEventTarget> mEventTargets[size_t(TaskCategory::Count)];
   RefPtr<AbstractThread> mAbstractThreads[size_t(TaskCategory::Count)];
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // defined(TabGroup_h)