/* static */ already_AddRefed<BrowsingContext> BrowsingContext::Get(uint64_t aId) { if (BrowsingContextMap<WeakPtr>::Ptr abc = sBrowsingContexts->lookup(aId)) { return do_AddRef(abc->value().get()); } return nullptr; }
void BrowsingContext::Detach(bool aFromIPC) { MOZ_LOG(GetLog(), LogLevel::Debug, ("%s: Detaching 0x%08" PRIx64 " from 0x%08" PRIx64, XRE_IsParentProcess() ? "Parent" : "Child", Id(), mParent ? mParent->Id() : 0)); RefPtr<BrowsingContext> kungFuDeathGrip(this); BrowsingContextMap<RefPtr>::Ptr p; if (sCachedBrowsingContexts && (p = sCachedBrowsingContexts->lookup(Id()))) { MOZ_DIAGNOSTIC_ASSERT(!mParent || !mParent->mChildren.Contains(this)); MOZ_DIAGNOSTIC_ASSERT(!mGroup || !mGroup->Toplevels().Contains(this)); sCachedBrowsingContexts->remove(p); } else { Children* children = nullptr; if (mParent) { children = &mParent->mChildren; } else if (mGroup) { children = &mGroup->Toplevels(); } if (children) { // TODO(farre): This assert looks extremely fishy, I know, but // what we're actually saying is this: if we're detaching, but our // parent doesn't have any children, it is because we're being // detached by the cycle collector destroying docshells out of // order. MOZ_DIAGNOSTIC_ASSERT(children->IsEmpty() || children->Contains(this)); children->RemoveElement(this); } } if (mGroup) { mGroup->Unregister(this); } // As our nsDocShell is going away, this should implicitly mark us as closed. // We directly set our member, rather than using a transaction as we're going // to send a `Detach` message to other processes either way. mClosed = true; if (!aFromIPC && XRE_IsContentProcess()) { auto cc = ContentChild::GetSingleton(); MOZ_DIAGNOSTIC_ASSERT(cc); cc->SendDetachBrowsingContext(this, false /* aMoveToBFCache */); } }