Bug 1121701, don't let network connections from the previous page to disturb restoration of a page from bfcache, r=bz

--HG--
extra : rebase_source : 27669a8962b2c8ed7cc6add444657ee4b3dc5752
This commit is contained in:
Olli Pettay 2015-01-22 22:37:56 +02:00
parent 9052a02f04
commit bb5404ea5e
2 changed files with 51 additions and 9 deletions

View File

@ -8233,14 +8233,6 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, bool *aRestoring)
SetHistoryEntry(&mLSHE, aSHEntry);
// Add the request to our load group. We do this before swapping out
// the content viewers so that consumers of STATE_START can access
// the old document. We only deal with the toplevel load at this time --
// to be consistent with normal document loading, subframes cannot start
// loading until after data arrives, which is after STATE_START completes.
BeginRestore(viewer, true);
// Post an event that will remove the request after we've returned
// to the event loop. This mimics the way it is called by nsIChannel
// implementations.
@ -8262,10 +8254,40 @@ nsDocShell::RestorePresentation(nsISHEntry *aSHEntry, bool *aRestoring)
return rv;
}
namespace {
class MOZ_STACK_CLASS PresentationEventForgetter
{
public:
explicit PresentationEventForgetter(
nsRevocableEventPtr<nsDocShell::RestorePresentationEvent>& aRestorePresentationEvent)
: mRestorePresentationEvent(aRestorePresentationEvent)
, mEvent(aRestorePresentationEvent.get())
{
}
~PresentationEventForgetter()
{
Forget();
}
void Forget()
{
if (mRestorePresentationEvent.get() == mEvent) {
mRestorePresentationEvent.Forget();
mEvent = nullptr;
}
}
private:
nsRevocableEventPtr<nsDocShell::RestorePresentationEvent>& mRestorePresentationEvent;
nsRefPtr<nsDocShell::RestorePresentationEvent> mEvent;
};
}
nsresult
nsDocShell::RestoreFromHistory()
{
mRestorePresentationEvent.Forget();
MOZ_ASSERT(mRestorePresentationEvent.IsPending());
PresentationEventForgetter forgetter(mRestorePresentationEvent);
// This section of code follows the same ordering as CreateContentViewer.
if (!mLSHE)
@ -8319,6 +8341,24 @@ nsDocShell::RestoreFromHistory()
if (mLSHE != origLSHE)
return NS_OK;
// Add the request to our load group. We do this before swapping out
// the content viewers so that consumers of STATE_START can access
// the old document. We only deal with the toplevel load at this time --
// to be consistent with normal document loading, subframes cannot start
// loading until after data arrives, which is after STATE_START completes.
nsRefPtr<RestorePresentationEvent> currentPresentationRestoration =
mRestorePresentationEvent.get();
Stop();
// Make sure we're still restoring the same presentation.
// If we aren't, docshell is in process doing another load already.
NS_ENSURE_STATE(currentPresentationRestoration ==
mRestorePresentationEvent.get());
BeginRestore(viewer, true);
NS_ENSURE_STATE(currentPresentationRestoration ==
mRestorePresentationEvent.get());
forgetter.Forget();
// Set mFiredUnloadEvent = false so that the unload handler for the
// *new* document will fire.
mFiredUnloadEvent = false;

View File

@ -693,6 +693,7 @@ protected:
*/
void MaybeInitTiming();
public:
// Event type dispatched by RestorePresentation
class RestorePresentationEvent : public nsRunnable {
public:
@ -702,6 +703,7 @@ protected:
private:
nsRefPtr<nsDocShell> mDocShell;
};
protected:
bool JustStartedNetworkLoad();