mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	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()) {
 | 
			
		||||
    context = new CanonicalBrowsingContext(
 | 
			
		||||
        aParent, aOpener, aName, aId, aOriginProcess->ChildID(), Type::Content);
 | 
			
		||||
 | 
			
		||||
    context->Group()->Subscribe(aOriginProcess);
 | 
			
		||||
  } else {
 | 
			
		||||
    context = new BrowsingContext(aParent, aOpener, aName, aId, Type::Content);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,35 +11,36 @@
 | 
			
		|||
namespace mozilla {
 | 
			
		||||
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) {
 | 
			
		||||
  return aBrowsingContext->Group() == this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BrowsingContextGroup::Register(BrowsingContext* aBrowsingContext) {
 | 
			
		||||
  MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
 | 
			
		||||
  mContexts.PutEntry(aBrowsingContext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BrowsingContextGroup::Unregister(BrowsingContext* aBrowsingContext) {
 | 
			
		||||
  MOZ_DIAGNOSTIC_ASSERT(aBrowsingContext);
 | 
			
		||||
  mContexts.RemoveEntry(aBrowsingContext);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BrowsingContextGroup::BrowsingContextGroup() {
 | 
			
		||||
  sAllGroups->AppendElement(this);
 | 
			
		||||
void BrowsingContextGroup::Subscribe(ContentParent* aOriginProcess) {
 | 
			
		||||
  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() {
 | 
			
		||||
  if (sAllGroups) {
 | 
			
		||||
    sAllGroups->RemoveElement(this);
 | 
			
		||||
  for (auto iter = mSubscribers.Iter(); !iter.Done(); iter.Next()) {
 | 
			
		||||
    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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BrowsingContextGroup)
 | 
			
		||||
 | 
			
		||||
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_WRAPPERCACHE(BrowsingContextGroup, mContexts,
 | 
			
		||||
                                      mToplevels, mSubscribers)
 | 
			
		||||
 | 
			
		||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(BrowsingContextGroup, AddRef)
 | 
			
		||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(BrowsingContextGroup, Release)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
#define mozilla_dom_BrowsingContextGroup_h
 | 
			
		||||
 | 
			
		||||
#include "mozilla/dom/BrowsingContext.h"
 | 
			
		||||
#include "mozilla/dom/ContentParent.h"
 | 
			
		||||
#include "mozilla/StaticPtr.h"
 | 
			
		||||
#include "nsHashKeys.h"
 | 
			
		||||
#include "nsTArray.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -31,13 +32,19 @@ class BrowsingContextGroup final : public nsWrapperCache {
 | 
			
		|||
  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(BrowsingContextGroup)
 | 
			
		||||
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(BrowsingContextGroup)
 | 
			
		||||
 | 
			
		||||
  static void Init();
 | 
			
		||||
  typedef nsTHashtable<nsRefPtrHashKey<ContentParent>> ContentParents;
 | 
			
		||||
 | 
			
		||||
  // Interact with the list of BrowsingContexts.
 | 
			
		||||
  bool Contains(BrowsingContext* aContext);
 | 
			
		||||
  void Register(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
 | 
			
		||||
  // BrowsingContextGroup.
 | 
			
		||||
  BrowsingContext::Children& Toplevels() { return mToplevels; }
 | 
			
		||||
| 
						 | 
				
			
			@ -49,15 +56,13 @@ class BrowsingContextGroup final : public nsWrapperCache {
 | 
			
		|||
  JSObject* WrapObject(JSContext* aCx,
 | 
			
		||||
                       JS::Handle<JSObject*> aGivenProto) override;
 | 
			
		||||
 | 
			
		||||
  BrowsingContextGroup();
 | 
			
		||||
  BrowsingContextGroup() = default;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  friend class CanonicalBrowsingContext;
 | 
			
		||||
 | 
			
		||||
  ~BrowsingContextGroup();
 | 
			
		||||
 | 
			
		||||
  static StaticAutoPtr<nsTArray<RefPtr<BrowsingContextGroup>>> sAllGroups;
 | 
			
		||||
 | 
			
		||||
  // A BrowsingContextGroup contains a series of BrowsingContext objects. They
 | 
			
		||||
  // are addressed using a hashtable to avoid linear lookup when adding or
 | 
			
		||||
  // removing elements from the set.
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +70,8 @@ class BrowsingContextGroup final : public nsWrapperCache {
 | 
			
		|||
 | 
			
		||||
  // The set of toplevel browsing contexts in the current BrowsingContextGroup.
 | 
			
		||||
  BrowsingContext::Children mToplevels;
 | 
			
		||||
 | 
			
		||||
  ContentParents mSubscribers;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace dom
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,27 +30,6 @@ CanonicalBrowsingContext::CanonicalBrowsingContext(BrowsingContext* aParent,
 | 
			
		|||
  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>
 | 
			
		||||
CanonicalBrowsingContext::Get(uint64_t aId) {
 | 
			
		||||
  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,6 @@ class WindowGlobalParent;
 | 
			
		|||
// parent needs.
 | 
			
		||||
class CanonicalBrowsingContext final : public BrowsingContext {
 | 
			
		||||
 public:
 | 
			
		||||
  static void CleanupContexts(uint64_t aProcessId);
 | 
			
		||||
  static already_AddRefed<CanonicalBrowsingContext> Get(uint64_t aId);
 | 
			
		||||
  static CanonicalBrowsingContext* Cast(BrowsingContext* aContext);
 | 
			
		||||
  static const CanonicalBrowsingContext* Cast(const BrowsingContext* aContext);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,6 @@ namespace mozilla {
 | 
			
		|||
// The one time initialization for this module
 | 
			
		||||
nsresult InitDocShellModule() {
 | 
			
		||||
  mozilla::dom::BrowsingContext::Init();
 | 
			
		||||
  mozilla::dom::BrowsingContextGroup::Init();
 | 
			
		||||
  nsresult rv = nsSHistory::Startup();
 | 
			
		||||
  NS_ENSURE_SUCCESS(rv, rv);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,6 +39,7 @@
 | 
			
		|||
#include "mozilla/devtools/HeapSnapshotTempFileHelperParent.h"
 | 
			
		||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
 | 
			
		||||
#include "mozilla/dom/BrowsingContext.h"
 | 
			
		||||
#include "mozilla/dom/BrowsingContextGroup.h"
 | 
			
		||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
 | 
			
		||||
#include "mozilla/dom/ClientManager.h"
 | 
			
		||||
#include "mozilla/dom/ClientOpenWindowOpActors.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -1743,7 +1744,14 @@ void ContentParent::ActorDestroy(ActorDestroyReason why) {
 | 
			
		|||
  a11y::AccessibleWrap::ReleaseContentProcessIdFor(ChildID());
 | 
			
		||||
#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() {
 | 
			
		||||
| 
						 | 
				
			
			@ -5820,6 +5828,18 @@ mozilla::ipc::IPCResult ContentParent::RecvWindowPostMessage(
 | 
			
		|||
  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 mozilla
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,7 @@ struct TextureFactoryIdentifier;
 | 
			
		|||
 | 
			
		||||
namespace dom {
 | 
			
		||||
 | 
			
		||||
class BrowsingContextGroup;
 | 
			
		||||
class Element;
 | 
			
		||||
class TabParent;
 | 
			
		||||
class ClonedMessageData;
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +123,7 @@ class ContentParent final : public PContentParent,
 | 
			
		|||
  typedef mozilla::ipc::URIParams URIParams;
 | 
			
		||||
  typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
 | 
			
		||||
  typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 | 
			
		||||
  typedef mozilla::dom::BrowsingContextGroup BrowsingContextGroup;
 | 
			
		||||
 | 
			
		||||
  friend class mozilla::PreallocatedProcessManagerImpl;
 | 
			
		||||
  friend class PContentParent;
 | 
			
		||||
| 
						 | 
				
			
			@ -1191,6 +1193,9 @@ class ContentParent final : public PContentParent,
 | 
			
		|||
    return mRecordReplayState != eNotRecordingOrReplaying;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void OnBrowsingContextGroupSubscribe(BrowsingContextGroup* aGroup);
 | 
			
		||||
  void OnBrowsingContextGroupUnsubscribe(BrowsingContextGroup* aGroup);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  // Released in ActorDestroy; deliberately not exposed to the CC.
 | 
			
		||||
  RefPtr<ContentParent> mSelfRef;
 | 
			
		||||
| 
						 | 
				
			
			@ -1326,6 +1331,8 @@ class ContentParent final : public PContentParent,
 | 
			
		|||
  // for the SetProcessSandbox IPDL message.
 | 
			
		||||
  static bool sEarlySandboxInit;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  nsTHashtable<nsRefPtrHashKey<BrowsingContextGroup>> mGroups;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace dom
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue