зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1589054 - Part 2: Delay pagehide events until new nsFrameLoader is set up, r=farre
If these are fired too early, a nested event loop can be spun before the new nsFrameLoader has been set up. Messages can be received over the BrowserBridgeChild actor during this time when no nsFrameLoader is set, causing crashes. Differential Revision: https://phabricator.services.mozilla.com/D49647 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a3cad4162e
Коммит
bc9c3bb08c
|
@ -90,34 +90,42 @@ void nsFrameLoaderOwner::ChangeRemotenessCommon(
|
|||
doc->BlockOnload();
|
||||
auto cleanup = MakeScopeExit([&]() { doc->UnblockOnload(false); });
|
||||
|
||||
// If we already have a Frameloader, destroy it, possibly preserving its
|
||||
// browsing context.
|
||||
if (mFrameLoader) {
|
||||
if (aPreserveContext) {
|
||||
bc = mFrameLoader->GetBrowsingContext();
|
||||
mFrameLoader->SkipBrowsingContextDetach();
|
||||
{
|
||||
// Introduce a script blocker to ensure no JS is executed during the
|
||||
// nsFrameLoader teardown & recreation process. Unload listeners will be run
|
||||
// for the previous document, and the load will be started for the new one,
|
||||
// at the end of this block.
|
||||
nsAutoScriptBlocker sb;
|
||||
|
||||
// If we already have a Frameloader, destroy it, possibly preserving its
|
||||
// browsing context.
|
||||
if (mFrameLoader) {
|
||||
if (aPreserveContext) {
|
||||
bc = mFrameLoader->GetBrowsingContext();
|
||||
mFrameLoader->SkipBrowsingContextDetach();
|
||||
}
|
||||
|
||||
// Preserve the networkCreated status, as nsDocShells created after a
|
||||
// process swap may shouldn't change their dynamically-created status.
|
||||
networkCreated = mFrameLoader->IsNetworkCreated();
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
}
|
||||
|
||||
// Preserve the networkCreated status, as nsDocShells created after a
|
||||
// process swap may shouldn't change their dynamically-created status.
|
||||
networkCreated = mFrameLoader->IsNetworkCreated();
|
||||
mFrameLoader->Destroy();
|
||||
mFrameLoader = nullptr;
|
||||
}
|
||||
mFrameLoader =
|
||||
nsFrameLoader::Recreate(owner, bc, aRemoteType, networkCreated);
|
||||
if (NS_WARN_IF(!mFrameLoader)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
mFrameLoader =
|
||||
nsFrameLoader::Recreate(owner, bc, aRemoteType, networkCreated);
|
||||
if (NS_WARN_IF(!mFrameLoader)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Invoke the frame loader initialization callback to perform setup on our new
|
||||
// nsFrameLoader. This may cause our ErrorResult to become errored, so
|
||||
// double-check after calling.
|
||||
aFrameLoaderInit();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
// Invoke the frame loader initialization callback to perform setup on our
|
||||
// new nsFrameLoader. This may cause our ErrorResult to become errored, so
|
||||
// double-check after calling.
|
||||
aFrameLoaderInit();
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we've got a new FrameLoader, we need to reset our
|
||||
|
|
Загрузка…
Ссылка в новой задаче