Bug 968804 - Part b: Add outer window assertions to {Can,Force,Final}Close; r=peterv
authorMs2ger <ms2ger@gmail.com>
Tue, 20 May 2014 21:50:58 +0200
changeset 184007 ee76827715891630014801ad59ac7f022641964f
parent 184006 f5c8ca9dbaf6c24f25950e49894be359d1c4de8c
child 184008 b781793ab79f348a924196022276a3f59bcb270f
push id26810
push usercbook@mozilla.com
push dateWed, 21 May 2014 11:46:36 +0000
treeherdermozilla-central@50fb8c4db2fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv
bugs968804
milestone32.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 968804 - Part b: Add outer window assertions to {Can,Force,Final}Close; r=peterv
dom/base/nsGlobalWindow.cpp
dom/base/nsGlobalWindow.h
dom/base/nsPIDOMWindow.h
toolkit/components/startup/nsAppStartup.cpp
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -8213,18 +8213,21 @@ public:
     return NS_OK;
   }
 
 };
 
 bool
 nsGlobalWindow::CanClose()
 {
-  if (!mDocShell)
+  MOZ_ASSERT(IsOuterWindow());
+
+  if (!mDocShell) {
     return true;
+  }
 
   // Ask the content viewer whether the toplevel window can close.
   // If the content viewer returns false, it is responsible for calling
   // Close() as soon as it is possible for the window to close.
   // This allows us to not close the window while printing is happening.
 
   nsCOMPtr<nsIContentViewer> cv;
   mDocShell->GetContentViewer(getter_AddRefs(cv));
@@ -8308,54 +8311,57 @@ nsGlobalWindow::Close(ErrorResult& aErro
   if (!DispatchCustomEvent("DOMWindowClose")) {
     // Someone chose to prevent the default action for this event, if
     // so, let's not close this window after all...
 
     mInClose = wasInClose;
     return;
   }
 
-  aError = FinalClose();
+  FinalClose();
 }
 
 NS_IMETHODIMP
 nsGlobalWindow::Close()
 {
   ErrorResult rv;
   Close(rv);
 
   return rv.ErrorCode();
 }
 
-nsresult
+void
 nsGlobalWindow::ForceClose()
 {
+  MOZ_ASSERT(IsOuterWindow());
+
   if (IsFrame() || !mDocShell) {
     // This may be a frame in a frameset, or a window that's already closed.
     // Ignore such calls.
-
-    return NS_OK;
+    return;
   }
 
   if (mHavePendingClose) {
     // We're going to be closed anyway; do nothing since we don't want
     // to double-close
-    return NS_OK;
+    return;
   }
 
   mInClose = true;
 
   DispatchCustomEvent("DOMWindowClose");
 
-  return FinalClose();
-}
-
-nsresult
+  FinalClose();
+}
+
+void
 nsGlobalWindow::FinalClose()
 {
+  MOZ_ASSERT(IsOuterWindow());
+
   // Flag that we were closed.
   mIsClosed = true;
 
   // This stuff is non-sensical but incredibly fragile. The reasons for the
   // behavior here don't make sense today and may not have ever made sense,
   // but various bits of frontend code break when you change them. If you need
   // to fix up this behavior, feel free to. It's a righteous task, but involves
   // wrestling with various download manager tests, frontend code, and possible
@@ -8369,18 +8375,16 @@ nsGlobalWindow::FinalClose()
   bool indirect = GetContextInternal() && // Occasionally null. See bug 877390.
                   (nsContentUtils::GetCurrentJSContext() ==
                    GetContextInternal()->GetNativeContext());
   if (NS_FAILED(nsCloseEvent::PostCloseEvent(this, indirect))) {
     ReallyCloseWindow();
   } else {
     mHavePendingClose = true;
   }
-
-  return NS_OK;
 }
 
 
 void
 nsGlobalWindow::ReallyCloseWindow()
 {
   FORWARD_TO_OUTER_VOID(ReallyCloseWindow, ());
 
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -465,18 +465,19 @@ public:
                                            bool aOriginalOpener);
 
   // Outer windows only.
   virtual NS_HIDDEN_(void) EnsureSizeUpToDate();
 
   virtual NS_HIDDEN_(void) EnterModalState();
   virtual NS_HIDDEN_(void) LeaveModalState();
 
+  // Outer windows only.
   virtual NS_HIDDEN_(bool) CanClose();
-  virtual NS_HIDDEN_(nsresult) ForceClose();
+  virtual NS_HIDDEN_(void) ForceClose();
 
   virtual NS_HIDDEN_(void) MaybeUpdateTouchState();
   virtual NS_HIDDEN_(void) UpdateTouchState();
   virtual NS_HIDDEN_(bool) DispatchCustomEvent(const char *aEventName);
   virtual NS_HIDDEN_(bool) DispatchResizeEvent(const nsIntSize& aSize);
   virtual NS_HIDDEN_(void) RefreshCompartmentPrincipal();
   virtual NS_HIDDEN_(nsresult) SetFullScreenInternal(bool aIsFullScreen, bool aRequireTrust);
 
@@ -1040,17 +1041,18 @@ protected:
   friend class HashchangeCallback;
   friend class mozilla::dom::BarProp;
 
   // Object Management
   virtual ~nsGlobalWindow();
   void DropOuterWindowDocs();
   void CleanUp();
   void ClearControllers();
-  nsresult FinalClose();
+  // Outer windows only.
+  void FinalClose();
 
   inline void MaybeClearInnerWindow(nsGlobalWindow* aExpectedInner)
   {
     if(mInnerWindow == aExpectedInner) {
       mInnerWindow = nullptr;
     }
   }
 
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -419,18 +419,19 @@ public:
 
   /**
    * Callback for notifying a window about a modal dialog being
    * opened/closed with the window as a parent.
    */
   virtual void EnterModalState() = 0;
   virtual void LeaveModalState() = 0;
 
+  // Outer windows only.
   virtual bool CanClose() = 0;
-  virtual nsresult ForceClose() = 0;
+  virtual void ForceClose() = 0;
 
   bool IsModalContentWindow() const
   {
     return mIsModalContentWindow;
   }
 
   /**
    * Call this to indicate that some node (this window, its document,
--- a/toolkit/components/startup/nsAppStartup.cpp
+++ b/toolkit/components/startup/nsAppStartup.cpp
@@ -358,16 +358,17 @@ nsAppStartup::Quit(uint32_t aMode)
       mediator->GetEnumerator(nullptr, getter_AddRefs(windowEnumerator));
       if (windowEnumerator) {
         bool more;
         while (windowEnumerator->HasMoreElements(&more), more) {
           nsCOMPtr<nsISupports> window;
           windowEnumerator->GetNext(getter_AddRefs(window));
           nsCOMPtr<nsPIDOMWindow> domWindow(do_QueryInterface(window));
           if (domWindow) {
+            MOZ_ASSERT(domWindow->IsOuterWindow());
             if (!domWindow->CanClose())
               return NS_OK;
           }
         }
       }
     }
 
     PROFILER_MARKER("Shutdown start");
@@ -499,18 +500,20 @@ nsAppStartup::CloseAllWindows()
   bool more;
   while (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)) && more) {
     nsCOMPtr<nsISupports> isupports;
     if (NS_FAILED(windowEnumerator->GetNext(getter_AddRefs(isupports))))
       break;
 
     nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(isupports);
     NS_ASSERTION(window, "not an nsPIDOMWindow");
-    if (window)
+    if (window) {
+      MOZ_ASSERT(window->IsOuterWindow());
       window->ForceClose();
+    }
   }
 }
 
 NS_IMETHODIMP
 nsAppStartup::EnterLastWindowClosingSurvivalArea(void)
 {
   ++mConsiderQuitStopper;
   return NS_OK;