Bug 1535913 - Part 1: Orchestrate content BCG destruction from parent, r=farre

This should help avoid crashes caused when the content process has
already destroyed a BCG when the parent process hasn't yet. The BCG will
still be destroyed when the content process shuts down using normal
cycle-collection.

Differential Revision: https://phabricator.services.mozilla.com/D113828
This commit is contained in:
Nika Layzell
2021-05-26 15:25:43 +00:00
parent 86acd8e17e
commit 0c6c37ac04
7 changed files with 68 additions and 30 deletions

View File

@@ -817,22 +817,6 @@ void BrowsingContext::Detach(bool aFromIPC) {
mGroup->Toplevels().RemoveElement(this);
}
auto callSendDiscard = [&](auto* aActor) {
// Hold a strong reference to ourself, and keep our BrowsingContextGroup
// alive, until the responses comes back to ensure we don't die while
// messages relating to this context are in-flight.
//
// When the callback is called, the keepalive on our group will be
// destroyed, and the reference to the BrowsingContext will be dropped,
// which may cause it to be fully destroyed.
mGroup->AddKeepAlive();
auto callback = [self = RefPtr{this}](auto) {
self->mGroup->RemoveKeepAlive();
};
aActor->SendDiscardBrowsingContext(this, callback, callback);
};
if (XRE_IsParentProcess()) {
Group()->EachParent([&](ContentParent* aParent) {
// Only the embedder process is allowed to initiate a BrowsingContext
@@ -844,11 +828,25 @@ void BrowsingContext::Detach(bool aFromIPC) {
// destroyed.
if (!Canonical()->IsEmbeddedInProcess(aParent->ChildID()) &&
!Canonical()->IsOwnedByProcess(aParent->ChildID())) {
callSendDiscard(aParent);
// Hold a strong reference to ourself, and keep our BrowsingContextGroup
// alive, until the responses comes back to ensure we don't die while
// messages relating to this context are in-flight.
//
// When the callback is called, the keepalive on our group will be
// destroyed, and the reference to the BrowsingContext will be dropped,
// which may cause it to be fully destroyed.
mGroup->AddKeepAlive();
auto callback = [self = RefPtr{this}](auto) {
self->mGroup->RemoveKeepAlive();
};
aParent->SendDiscardBrowsingContext(this, callback, callback);
}
});
} else if (!aFromIPC) {
callSendDiscard(ContentChild::GetSingleton());
auto callback = [](auto) {};
ContentChild::GetSingleton()->SendDiscardBrowsingContext(this, callback,
callback);
}
mGroup->Unregister(this);