forked from mirrors/gecko-dev
Bug 1525887 - Add set of ContentParent subscribed to BrowsingContextGroup. r=nika
Add the origin ContentParent to a CanonicalBrowsingContext's group when a CanonicalBrowsingContext is created from IPC. With this it is possible to keep track of all child processes associated with a BrowsingContextGroup. Differential Revision: https://phabricator.services.mozilla.com/D19004 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
dac519208a
commit
1877793bdc
8 changed files with 58 additions and 56 deletions
|
|
@ -148,6 +148,8 @@ CanonicalBrowsingContext* BrowsingContext::Canonical() {
|
||||||
if (XRE_IsParentProcess()) {
|
if (XRE_IsParentProcess()) {
|
||||||
context = new CanonicalBrowsingContext(
|
context = new CanonicalBrowsingContext(
|
||||||
aParent, aOpener, aName, aId, aOriginProcess->ChildID(), Type::Content);
|
aParent, aOpener, aName, aId, aOriginProcess->ChildID(), Type::Content);
|
||||||
|
|
||||||
|
context->Group()->Subscribe(aOriginProcess);
|
||||||
} else {
|
} else {
|
||||||
context = new BrowsingContext(aParent, aOpener, aName, aId, Type::Content);
|
context = new BrowsingContext(aParent, aOpener, aName, aId, Type::Content);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,35 +11,36 @@
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
StaticAutoPtr<nsTArray<RefPtr<BrowsingContextGroup>>>
|
|
||||||
BrowsingContextGroup::sAllGroups;
|
|
||||||
|
|
||||||
/* static */ void BrowsingContextGroup::Init() {
|
|
||||||
if (!sAllGroups) {
|
|
||||||
sAllGroups = new nsTArray<RefPtr<BrowsingContextGroup>>();
|
|
||||||
ClearOnShutdown(&sAllGroups);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowsingContextGroup::Contains(BrowsingContext* aBrowsingContext) {
|
bool BrowsingContextGroup::Contains(BrowsingContext* aBrowsingContext) {
|
||||||
return aBrowsingContext->Group() == this;
|
return aBrowsingContext->Group() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowsingContextGroup::Register(BrowsingContext* aBrowsingContext) {
|
void BrowsingContextGroup::Register(BrowsingContext* aBrowsingContext) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
|
||||||
mContexts.PutEntry(aBrowsingContext);
|
mContexts.PutEntry(aBrowsingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowsingContextGroup::Unregister(BrowsingContext* aBrowsingContext) {
|
void BrowsingContextGroup::Unregister(BrowsingContext* aBrowsingContext) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
|
||||||
mContexts.RemoveEntry(aBrowsingContext);
|
mContexts.RemoveEntry(aBrowsingContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowsingContextGroup::BrowsingContextGroup() {
|
void BrowsingContextGroup::Subscribe(ContentParent* aOriginProcess) {
|
||||||
sAllGroups->AppendElement(this);
|
MOZ_DIAGNOSTIC_ASSERT(aOriginProcess);
|
||||||
|
mSubscribers.PutEntry(aOriginProcess);
|
||||||
|
aOriginProcess->OnBrowsingContextGroupSubscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BrowsingContextGroup::Unsubscribe(ContentParent* aOriginProcess) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aOriginProcess);
|
||||||
|
mSubscribers.RemoveEntry(aOriginProcess);
|
||||||
|
aOriginProcess->OnBrowsingContextGroupUnsubscribe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowsingContextGroup::~BrowsingContextGroup() {
|
BrowsingContextGroup::~BrowsingContextGroup() {
|
||||||
if (sAllGroups) {
|
for (auto iter = mSubscribers.Iter(); !iter.Done(); iter.Next()) {
|
||||||
sAllGroups->RemoveElement(this);
|
nsRefPtrHashKey<ContentParent>* entry = iter.Get();
|
||||||
|
entry->GetKey()->OnBrowsingContextGroupUnsubscribe(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,20 +53,8 @@ JSObject* BrowsingContextGroup::WrapObject(JSContext* aCx,
|
||||||
return BrowsingContextGroup_Binding::Wrap(aCx, this, aGivenProto);
|
return BrowsingContextGroup_Binding::Wrap(aCx, this, aGivenProto);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContextGroup)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(BrowsingContextGroup, mContexts,
|
||||||
|
mToplevels, mSubscribers)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(BrowsingContextGroup)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mContexts)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mToplevels)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(BrowsingContextGroup)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContexts)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mToplevels)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(BrowsingContextGroup)
|
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContextGroup, AddRef)
|
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContextGroup, AddRef)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContextGroup, Release)
|
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContextGroup, Release)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#define mozilla_dom_BrowsingContextGroup_h
|
#define mozilla_dom_BrowsingContextGroup_h
|
||||||
|
|
||||||
#include "mozilla/dom/BrowsingContext.h"
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/StaticPtr.h"
|
#include "mozilla/StaticPtr.h"
|
||||||
#include "nsHashKeys.h"
|
#include "nsHashKeys.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
|
@ -31,13 +32,19 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContextGroup)
|
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContextGroup)
|
||||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(BrowsingContextGroup)
|
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(BrowsingContextGroup)
|
||||||
|
|
||||||
static void Init();
|
typedef nsTHashtable<nsRefPtrHashKey<ContentParent>> ContentParents;
|
||||||
|
|
||||||
// Interact with the list of BrowsingContexts.
|
// Interact with the list of BrowsingContexts.
|
||||||
bool Contains(BrowsingContext* aContext);
|
bool Contains(BrowsingContext* aContext);
|
||||||
void Register(BrowsingContext* aContext);
|
void Register(BrowsingContext* aContext);
|
||||||
void Unregister(BrowsingContext* aContext);
|
void Unregister(BrowsingContext* aContext);
|
||||||
|
|
||||||
|
// Interact with the list of ContentParents
|
||||||
|
void Subscribe(ContentParent* aOriginProcess);
|
||||||
|
void Unsubscribe(ContentParent* aOriginProcess);
|
||||||
|
|
||||||
|
ContentParents::Iterator ContentParentsIter() { return mSubscribers.Iter(); }
|
||||||
|
|
||||||
// Get a reference to the list of toplevel contexts in this
|
// Get a reference to the list of toplevel contexts in this
|
||||||
// BrowsingContextGroup.
|
// BrowsingContextGroup.
|
||||||
BrowsingContext::Children& Toplevels() { return mToplevels; }
|
BrowsingContext::Children& Toplevels() { return mToplevels; }
|
||||||
|
|
@ -49,15 +56,13 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||||
JSObject* WrapObject(JSContext* aCx,
|
JSObject* WrapObject(JSContext* aCx,
|
||||||
JS::Handle<JSObject*> aGivenProto) override;
|
JS::Handle<JSObject*> aGivenProto) override;
|
||||||
|
|
||||||
BrowsingContextGroup();
|
BrowsingContextGroup() = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CanonicalBrowsingContext;
|
friend class CanonicalBrowsingContext;
|
||||||
|
|
||||||
~BrowsingContextGroup();
|
~BrowsingContextGroup();
|
||||||
|
|
||||||
static StaticAutoPtr<nsTArray<RefPtr<BrowsingContextGroup>>> sAllGroups;
|
|
||||||
|
|
||||||
// A BrowsingContextGroup contains a series of BrowsingContext objects. They
|
// A BrowsingContextGroup contains a series of BrowsingContext objects. They
|
||||||
// are addressed using a hashtable to avoid linear lookup when adding or
|
// are addressed using a hashtable to avoid linear lookup when adding or
|
||||||
// removing elements from the set.
|
// removing elements from the set.
|
||||||
|
|
@ -65,6 +70,8 @@ class BrowsingContextGroup final : public nsWrapperCache {
|
||||||
|
|
||||||
// The set of toplevel browsing contexts in the current BrowsingContextGroup.
|
// The set of toplevel browsing contexts in the current BrowsingContextGroup.
|
||||||
BrowsingContext::Children mToplevels;
|
BrowsingContext::Children mToplevels;
|
||||||
|
|
||||||
|
ContentParents mSubscribers;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
|
|
@ -30,27 +30,6 @@ CanonicalBrowsingContext::CanonicalBrowsingContext(BrowsingContext* aParent,
|
||||||
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(farre): CanonicalBrowsingContext::CleanupContexts starts from the
|
|
||||||
// list of root BrowsingContexts. This isn't enough when separate
|
|
||||||
// BrowsingContext nodes of a BrowsingContext tree, not in a crashing
|
|
||||||
// child process, are from that process and thus needs to be
|
|
||||||
// cleaned. [Bug 1472108]
|
|
||||||
/* static */ void CanonicalBrowsingContext::CleanupContexts(
|
|
||||||
uint64_t aProcessId) {
|
|
||||||
nsTArray<RefPtr<BrowsingContext>> contexts;
|
|
||||||
for (auto& group : *BrowsingContextGroup::sAllGroups) {
|
|
||||||
for (auto& context : group->Toplevels()) {
|
|
||||||
if (Cast(context)->IsOwnedByProcess(aProcessId)) {
|
|
||||||
contexts.AppendElement(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& context : contexts) {
|
|
||||||
context->Detach();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* static */ already_AddRefed<CanonicalBrowsingContext>
|
/* static */ already_AddRefed<CanonicalBrowsingContext>
|
||||||
CanonicalBrowsingContext::Get(uint64_t aId) {
|
CanonicalBrowsingContext::Get(uint64_t aId) {
|
||||||
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ class WindowGlobalParent;
|
||||||
// parent needs.
|
// parent needs.
|
||||||
class CanonicalBrowsingContext final : public BrowsingContext {
|
class CanonicalBrowsingContext final : public BrowsingContext {
|
||||||
public:
|
public:
|
||||||
static void CleanupContexts(uint64_t aProcessId);
|
|
||||||
static already_AddRefed<CanonicalBrowsingContext> Get(uint64_t aId);
|
static already_AddRefed<CanonicalBrowsingContext> Get(uint64_t aId);
|
||||||
static CanonicalBrowsingContext* Cast(BrowsingContext* aContext);
|
static CanonicalBrowsingContext* Cast(BrowsingContext* aContext);
|
||||||
static const CanonicalBrowsingContext* Cast(const BrowsingContext* aContext);
|
static const CanonicalBrowsingContext* Cast(const BrowsingContext* aContext);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ namespace mozilla {
|
||||||
// The one time initialization for this module
|
// The one time initialization for this module
|
||||||
nsresult InitDocShellModule() {
|
nsresult InitDocShellModule() {
|
||||||
mozilla::dom::BrowsingContext::Init();
|
mozilla::dom::BrowsingContext::Init();
|
||||||
mozilla::dom::BrowsingContextGroup::Init();
|
|
||||||
nsresult rv = nsSHistory::Startup();
|
nsresult rv = nsSHistory::Startup();
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
|
||||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||||
#include "mozilla/dom/BrowsingContext.h"
|
#include "mozilla/dom/BrowsingContext.h"
|
||||||
|
#include "mozilla/dom/BrowsingContextGroup.h"
|
||||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||||
#include "mozilla/dom/ClientManager.h"
|
#include "mozilla/dom/ClientManager.h"
|
||||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
#include "mozilla/dom/ClientOpenWindowOpActors.h"
|
||||||
|
|
@ -1743,7 +1744,14 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
|
||||||
a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
|
a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CanonicalBrowsingContext::CleanupContexts(ChildID());
|
nsTHashtable<nsRefPtrHashKey<BrowsingContextGroup>> groups;
|
||||||
|
mGroups.SwapElements(groups);
|
||||||
|
|
||||||
|
for (auto iter = groups.Iter(); !iter.Done(); iter.Next()) {
|
||||||
|
iter.Get()->GetKey()->Unsubscribe(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(mGroups.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ContentParent::TryToRecycle() {
|
bool ContentParent::TryToRecycle() {
|
||||||
|
|
@ -5820,6 +5828,18 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowPostMessage(
|
||||||
return IPC_OK();
|
return IPC_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentParent::OnBrowsingContextGroupSubscribe(
|
||||||
|
BrowsingContextGroup* aGroup) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aGroup);
|
||||||
|
mGroups.PutEntry(aGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentParent::OnBrowsingContextGroupUnsubscribe(
|
||||||
|
BrowsingContextGroup* aGroup) {
|
||||||
|
MOZ_DIAGNOSTIC_ASSERT(aGroup);
|
||||||
|
mGroups.RemoveEntry(aGroup);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,7 @@ struct TextureFactoryIdentifier;
|
||||||
|
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
class BrowsingContextGroup;
|
||||||
class Element;
|
class Element;
|
||||||
class TabParent;
|
class TabParent;
|
||||||
class ClonedMessageData;
|
class ClonedMessageData;
|
||||||
|
|
@ -122,6 +123,7 @@ class ContentParent final : public PContentParent,
|
||||||
typedef mozilla::ipc::URIParams URIParams;
|
typedef mozilla::ipc::URIParams URIParams;
|
||||||
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
||||||
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
|
||||||
|
typedef mozilla::dom::BrowsingContextGroup BrowsingContextGroup;
|
||||||
|
|
||||||
friend class mozilla::PreallocatedProcessManagerImpl;
|
friend class mozilla::PreallocatedProcessManagerImpl;
|
||||||
friend class PContentParent;
|
friend class PContentParent;
|
||||||
|
|
@ -1191,6 +1193,9 @@ class ContentParent final : public PContentParent,
|
||||||
return mRecordReplayState != eNotRecordingOrReplaying;
|
return mRecordReplayState != eNotRecordingOrReplaying;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OnBrowsingContextGroupSubscribe(BrowsingContextGroup* aGroup);
|
||||||
|
void OnBrowsingContextGroupUnsubscribe(BrowsingContextGroup* aGroup);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Released in ActorDestroy; deliberately not exposed to the CC.
|
// Released in ActorDestroy; deliberately not exposed to the CC.
|
||||||
RefPtr<ContentParent> mSelfRef;
|
RefPtr<ContentParent> mSelfRef;
|
||||||
|
|
@ -1326,6 +1331,8 @@ class ContentParent final : public PContentParent,
|
||||||
// for the SetProcessSandbox IPDL message.
|
// for the SetProcessSandbox IPDL message.
|
||||||
static bool sEarlySandboxInit;
|
static bool sEarlySandboxInit;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nsTHashtable<nsRefPtrHashKey<BrowsingContextGroup>> mGroups;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue