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
	
	 Andreas Farre
						Andreas Farre