Bug 893324 - Invoke CleanUp synchronously and unconditionally for modal dialog windows. r=jst

Historically, we've had a bunch of complicated machinery to delay the call to
CleanUp() for modal dialogs, since we needed to harvest the return value after
the window closed. But in the current world we don't actually null out
mReturnValue in CleanUp() at all, which presumably happened sometime around the
time mReturnValue became cycle-collected. So this stuff can just go away. \o/

That simplification is righteous in itself. But it also fixes the bug here as-
filed. When the user quits while a modal dialog is currently being displayed,
a failure code ends up bubbling up through windowWatcher to the OpenInternal call
in nsGlobalWindow::ShowModalDialog, which means that we're unable to do our
delayed CleanUp() call for the outer modal window. At first it seemed like a hard
problem to solve, but with the above it becomes trivial.
This commit is contained in:
Bobby Holley 2013-07-26 15:46:13 -07:00
parent 26e5c13d44
commit 38ba111543
2 changed files with 7 additions and 25 deletions

View File

@ -1035,7 +1035,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
mSetOpenerWindowCalled(false),
#endif
mCleanedUp(false),
mCallCleanUpAfterModalDialogCloses(false),
mDialogAbuseCount(0),
mStopAbuseDialogs(false),
mDialogsPermanentlyDisabled(false)
@ -1253,7 +1252,7 @@ nsGlobalWindow::~nsGlobalWindow()
// involve auditing all of the references that inners and outers can have, and
// separating the handling into CleanUp() and FreeInnerObjects.
if (IsInnerWindow()) {
CleanUp(true);
CleanUp();
} else {
MOZ_ASSERT(mCleanedUp);
}
@ -1323,20 +1322,8 @@ nsGlobalWindow::MaybeForgiveSpamCount()
}
void
nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
nsGlobalWindow::CleanUp()
{
if (IsOuterWindow() && !aIgnoreModalDialog) {
nsGlobalWindow* inner = GetCurrentInnerWindowInternal();
nsCOMPtr<nsIDOMModalContentWindow> dlg(do_QueryObject(inner));
if (dlg) {
// The window we're trying to clean up is the outer window of a
// modal dialog. Defer cleanup until the window closes, and let
// ShowModalDialog take care of calling CleanUp.
mCallCleanUpAfterModalDialogCloses = true;
return;
}
}
// Guarantee idempotence.
if (mCleanedUp)
return;
@ -1404,7 +1391,7 @@ nsGlobalWindow::CleanUp(bool aIgnoreModalDialog)
nsGlobalWindow *inner = GetCurrentInnerWindowInternal();
if (inner) {
inner->CleanUp(aIgnoreModalDialog);
inner->CleanUp();
}
DisableGamepadUpdates();
@ -2783,7 +2770,7 @@ nsGlobalWindow::DetachFromDocShell()
}
MaybeForgiveSpamCount();
CleanUp(false);
CleanUp();
}
void
@ -7247,7 +7234,7 @@ nsGlobalWindow::ReallyCloseWindow()
}
}
CleanUp(false);
CleanUp();
}
}
@ -7827,11 +7814,6 @@ nsGlobalWindow::ShowModalDialog(const nsAString& aURI, nsIVariant *aArgs_,
if (dialog) {
rv = dialog->GetReturnValue(aRetVal);
MOZ_ASSERT(NS_SUCCEEDED(rv));
nsGlobalModalWindow *win = static_cast<nsGlobalModalWindow*>(dialog.get());
if (win->mCallCleanUpAfterModalDialogCloses) {
win->mCallCleanUpAfterModalDialogCloses = false;
win->CleanUp(true);
}
}
return NS_OK;

View File

@ -809,7 +809,7 @@ protected:
// Object Management
virtual ~nsGlobalWindow();
void CleanUp(bool aIgnoreModalDialog);
void CleanUp();
void ClearControllers();
nsresult FinalClose();
@ -1244,7 +1244,7 @@ protected:
nsCOMPtr<nsIURI> mLastOpenedURI;
#endif
bool mCleanedUp, mCallCleanUpAfterModalDialogCloses;
bool mCleanedUp;
nsCOMPtr<nsIDOMOfflineResourceList> mApplicationCache;