Bug 1699721 - Part 2: Track BrowserParent lifecycles during process switches, r=kmag

This patch contains a large number of changes around the process switching
mechanism in order to avoid issues which are caused by a mismatched
understanding of the state of the process switch between processes in the
presence of nested event loops.

This includes:
 1. The "InFlightProcessId" value is no longer recorded. All remaining uses
    were removed in part 1, and the new mechanism tracks this information in
    a better way.
 2. The current BrowserParent instance is now tracked on
    CanonicalBrowsingContext, meaning that logic which needs to work with this
    information can now access it without depending on the current
    WindowGlobalParent instance.
 3. When doing a process switch, the previous host process for the
    BrowsingContext is tracked until the process switch is completed, allowing
    for future attempts to switch into that process to be delayed until the
    previous unload event has finished running.
 4. The process switch logic was refactored to simplify some of the
    error-handling logic, and share more code between different cases.

Differential Revision: https://phabricator.services.mozilla.com/D110002
This commit is contained in:
Nika Layzell
2021-03-31 16:51:58 +00:00
parent 543cc4f7cb
commit d5391a0517
11 changed files with 414 additions and 277 deletions

View File

@@ -439,6 +439,9 @@ already_AddRefed<BrowsingContext> BrowsingContext::CreateDetached(
already_AddRefed<BrowsingContext> BrowsingContext::CreateIndependent(
Type aType) {
MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess(),
"BCs created in the content process must be related to "
"some BrowserChild");
RefPtr<BrowsingContext> bc(
CreateDetached(nullptr, nullptr, nullptr, u""_ns, aType));
bc->mWindowless = bc->IsContent();
@@ -695,6 +698,7 @@ void BrowsingContext::Embed() {
void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
MOZ_DIAGNOSTIC_ASSERT(!mEverAttached);
MOZ_DIAGNOSTIC_ASSERT_IF(aFromIPC, aOriginProcess || XRE_IsContentProcess());
mEverAttached = true;
if (MOZ_LOG_TEST(GetLog(), LogLevel::Debug)) {
@@ -745,6 +749,18 @@ void BrowsingContext::Attach(bool aFromIPC, ContentParent* aOriginProcess) {
ContentChild::GetSingleton()->SendCreateBrowsingContext(
mGroup->Id(), GetIPCInitializer());
} else if (XRE_IsParentProcess()) {
// If this window was created as a subframe by a content process, it must be
// being hosted within the same BrowserParent as its mParentWindow.
// Toplevel BrowsingContexts created by content have their BrowserParent
// configured during `RecvConstructPopupBrowser`.
if (mParentWindow && aOriginProcess) {
MOZ_DIAGNOSTIC_ASSERT(
mParentWindow->Canonical()->GetContentParent() == aOriginProcess,
"Creator process isn't the same as our embedder?");
Canonical()->SetCurrentBrowserParent(
mParentWindow->Canonical()->GetBrowserParent());
}
mGroup->EachOtherParent(aOriginProcess, [&](ContentParent* aParent) {
MOZ_DIAGNOSTIC_ASSERT(IsContent(),
"chrome BCG cannot be synced to content process");