Bug 1547219 - Add helper for iterating ContentParents in BCG. r=nika
authorAndreas Farre <farre@mozilla.com>
Tue, 30 Apr 2019 08:45:41 +0000
changeset 530717 6faa9ec592f5a0fa1a7bca868f8e7eab6c37a346
parent 530716 29e3098206eae2c48d7852823325e909de015a6b
child 530718 ee6ceba037af625f039cffb8dae0c860cdda1bbe
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnika
bugs1547219
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1547219 - Add helper for iterating ContentParents in BCG. r=nika Differential Revision: https://phabricator.services.mozilla.com/D29152
docshell/base/BrowsingContext.cpp
docshell/base/BrowsingContextGroup.h
docshell/base/CanonicalBrowsingContext.cpp
dom/ipc/ContentParent.cpp
--- a/docshell/base/BrowsingContext.cpp
+++ b/docshell/base/BrowsingContext.cpp
@@ -259,23 +259,19 @@ void BrowsingContext::Attach(bool aFromI
 
   if (!aFromIPC) {
     // Send attach to our parent if we need to.
     if (XRE_IsContentProcess()) {
       ContentChild::GetSingleton()->SendAttachBrowsingContext(
           GetIPCInitializer());
     } else if (IsContent()) {
       MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
-      for (auto iter = Group()->ContentParentsIter(); !iter.Done();
-           iter.Next()) {
-        nsRefPtrHashKey<ContentParent>* entry = iter.Get();
-
-        Unused << entry->GetKey()->SendAttachBrowsingContext(
-            GetIPCInitializer());
-      }
+      Group()->EachParent([&](ContentParent* aParent) {
+        Unused << aParent->SendAttachBrowsingContext(GetIPCInitializer());
+      });
     }
   }
 }
 
 void BrowsingContext::Detach(bool aFromIPC) {
   MOZ_LOG(GetLog(), LogLevel::Debug,
           ("%s: Detaching 0x%08" PRIx64 " from 0x%08" PRIx64,
            XRE_IsParentProcess() ? "Parent" : "Child", Id(),
@@ -770,24 +766,23 @@ void BrowsingContext::Transaction::Commi
 #define MOZ_BC_FIELD(...) /* nothing */
 #include "mozilla/dom/BrowsingContextFieldList.h"
 
     ContentChild* cc = ContentChild::GetSingleton();
     cc->SendCommitBrowsingContextTransaction(aBrowsingContext, *this,
                                              aBrowsingContext->mFieldEpochs);
   } else {
     MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
-    for (auto iter = aBrowsingContext->Group()->ContentParentsIter();
-         !iter.Done(); iter.Next()) {
-      RefPtr<ContentParent> child = iter.Get()->GetKey();
+
+    aBrowsingContext->Group()->EachParent([&](ContentParent* aParent) {
       const FieldEpochs& childEpochs =
-          aBrowsingContext->Canonical()->GetFieldEpochsForChild(child);
-      Unused << child->SendCommitBrowsingContextTransaction(aBrowsingContext,
-                                                            *this, childEpochs);
-    }
+          aBrowsingContext->Canonical()->GetFieldEpochsForChild(aParent);
+      Unused << aParent->SendCommitBrowsingContextTransaction(
+          aBrowsingContext, *this, childEpochs);
+    });
   }
 
   Apply(aBrowsingContext, nullptr);
 }
 
 void BrowsingContext::Transaction::Apply(BrowsingContext* aBrowsingContext,
                                          ContentParent* aSource,
                                          const FieldEpochs* aEpochs) {
--- a/docshell/base/BrowsingContextGroup.h
+++ b/docshell/base/BrowsingContextGroup.h
@@ -46,18 +46,16 @@ class BrowsingContextGroup final : publi
   void EnsureSubscribed(ContentParent* aProcess);
 
   // Methods interacting with cached contexts.
   bool IsContextCached(BrowsingContext* aContext) const;
   void CacheContext(BrowsingContext* aContext);
   void CacheContexts(const BrowsingContext::Children& aContexts);
   bool EvictCachedContext(BrowsingContext* aContext);
 
-  ContentParents::Iterator ContentParentsIter() { return mSubscribers.Iter(); }
-
   // Get a reference to the list of toplevel contexts in this
   // BrowsingContextGroup.
   BrowsingContext::Children& Toplevels() { return mToplevels; }
   void GetToplevels(BrowsingContext::Children& aToplevels) {
     aToplevels.AppendElements(mToplevels);
   }
 
   nsISupports* GetParentObject() const;
@@ -83,16 +81,38 @@ class BrowsingContextGroup final : publi
     MOZ_RELEASE_ASSERT(parent || aParentId == 0);
 
     RefPtr<BrowsingContext> opener = BrowsingContext::Get(aOpenerId);
     MOZ_RELEASE_ASSERT(opener || aOpenerId == 0);
 
     return Select(parent, opener);
   }
 
+  // For each 'ContentParent', except for 'aExcludedParent',
+  // associated with this group call 'aCallback'.
+  template <typename Func>
+  void EachOtherParent(ContentParent* aExcludedParent, Func&& aCallback) {
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
+    for (auto iter = mSubscribers.Iter(); !iter.Done(); iter.Next()) {
+      if (iter.Get()->GetKey() != aExcludedParent) {
+        aCallback(iter.Get()->GetKey());
+      }
+    }
+  }
+
+  // For each 'ContentParent' associated with
+  // this group call 'aCallback'.
+  template <typename Func>
+  void EachParent(Func&& aCallback) {
+    MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess());
+    for (auto iter = mSubscribers.Iter(); !iter.Done(); iter.Next()) {
+      aCallback(iter.Get()->GetKey());
+    }
+  }
+
  private:
   friend class CanonicalBrowsingContext;
 
   ~BrowsingContextGroup();
 
   // 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.
--- a/docshell/base/CanonicalBrowsingContext.cpp
+++ b/docshell/base/CanonicalBrowsingContext.cpp
@@ -167,20 +167,20 @@ void CanonicalBrowsingContext::NotifySta
   // tab bar. That's clear user intent to play, so gesture activate the browsing
   // context so that the block-autoplay logic allows the media to autoplay.
   NotifyUserGestureActivation();
   AUTOPLAY_LOG("NotifyStartDelayedAutoplayMedia for chrome bc 0x%08" PRIx64,
                Id());
   StartDelayedAutoplayMediaComponents();
   // Notfiy all content browsing contexts which are related with the canonical
   // browsing content tree to start delayed autoplay media.
-  for (auto iter = Group()->ContentParentsIter(); !iter.Done(); iter.Next()) {
-    auto entry = iter.Get();
-    Unused << entry->GetKey()->SendStartDelayedAutoplayMediaComponents(this);
-  }
+
+  Group()->EachParent([&](ContentParent* aParent) {
+    Unused << aParent->SendStartDelayedAutoplayMediaComponents(this);
+  });
 }
 
 void CanonicalBrowsingContext::SetFieldEpochsForChild(
     ContentParent* aChild, const BrowsingContext::FieldEpochs& aEpochs) {
   mChildFieldEpochs.Put(aChild->ChildID(), aEpochs);
 }
 
 const BrowsingContext::FieldEpochs&
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5024,18 +5024,17 @@ mozilla::ipc::IPCResult ContentParent::R
     const uint32_t& aGeneration, const bool& aDefer, bool* aLoaded) {
   gfxPlatformFontList::PlatformFontList()->InitOtherFamilyNames(aGeneration,
                                                                 aDefer);
   *aLoaded = true;
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvSetupFamilyCharMap(
-    const uint32_t& aGeneration,
-    const mozilla::fontlist::Pointer& aFamilyPtr) {
+    const uint32_t& aGeneration, const mozilla::fontlist::Pointer& aFamilyPtr) {
   gfxPlatformFontList::PlatformFontList()->SetupFamilyCharMap(aGeneration,
                                                               aFamilyPtr);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvGraphicsError(
     const nsCString& aError) {
   gfx::LogForwarder* lf = gfx::Factory::GetLogForwarder();
@@ -5706,26 +5705,19 @@ mozilla::ipc::IPCResult ContentParent::R
   if (!child) {
     RefPtr<BrowsingContextGroup> group =
         BrowsingContextGroup::Select(aInit.mParentId, aInit.mOpenerId);
     child = BrowsingContext::CreateFromIPC(std::move(aInit), group, this);
   }
 
   child->Attach(/* aFromIPC */ true);
 
-  for (auto iter = child->Group()->ContentParentsIter(); !iter.Done();
-       iter.Next()) {
-    nsRefPtrHashKey<ContentParent>* entry = iter.Get();
-    if (entry->GetKey() == this) {
-      continue;
-    }
-
-    Unused << entry->GetKey()->SendAttachBrowsingContext(
-        child->GetIPCInitializer());
-  }
+  child->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
+    Unused << aParent->SendAttachBrowsingContext(child->GetIPCInitializer());
+  });
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvDetachBrowsingContext(
     BrowsingContext* aContext) {
   if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
@@ -5743,25 +5735,19 @@ mozilla::ipc::IPCResult ContentParent::R
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to detach out of process context 0x%08" PRIx64,
              aContext->Id()));
     return IPC_OK();
   }
 
   aContext->Detach(/* aFromIPC */ true);
 
-  for (auto iter = aContext->Group()->ContentParentsIter(); !iter.Done();
-       iter.Next()) {
-    nsRefPtrHashKey<ContentParent>* entry = iter.Get();
-    if (entry->GetKey() == this) {
-      continue;
-    }
-
-    Unused << entry->GetKey()->SendDetachBrowsingContext(aContext);
-  }
+  aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
+    Unused << aParent->SendDetachBrowsingContext(aContext);
+  });
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvCacheBrowsingContextChildren(
     BrowsingContext* aContext) {
   if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
@@ -5779,25 +5765,19 @@ mozilla::ipc::IPCResult ContentParent::R
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to cache out of process context 0x%08" PRIx64,
              aContext->Id()));
     return IPC_OK();
   }
 
   aContext->CacheChildren(/* aFromIPC */ true);
 
-  for (auto iter = aContext->Group()->ContentParentsIter(); !iter.Done();
-       iter.Next()) {
-    nsRefPtrHashKey<ContentParent>* entry = iter.Get();
-    if (entry->GetKey() == this) {
-      continue;
-    }
-
-    Unused << entry->GetKey()->SendCacheBrowsingContextChildren(aContext);
-  }
+  aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
+    Unused << aParent->SendCacheBrowsingContextChildren(aContext);
+  });
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult ContentParent::RecvRestoreBrowsingContextChildren(
     BrowsingContext* aContext, nsTArray<BrowsingContextId>&& aChildren) {
   if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Debug,
@@ -5822,26 +5802,19 @@ mozilla::ipc::IPCResult ContentParent::R
 
   for (auto id : aChildren) {
     RefPtr<BrowsingContext> child = BrowsingContext::Get(id);
     children.AppendElement(child);
   }
 
   aContext->RestoreChildren(std::move(children), /* aFromIPC */ true);
 
-  for (auto iter = aContext->Group()->ContentParentsIter(); !iter.Done();
-       iter.Next()) {
-    nsRefPtrHashKey<ContentParent>* entry = iter.Get();
-    if (entry->GetKey() == this) {
-      continue;
-    }
-
-    Unused << entry->GetKey()->SendRestoreBrowsingContextChildren(aContext,
-                                                                  aChildren);
-  }
+  aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
+    Unused << aParent->SendRestoreBrowsingContextChildren(aContext, aChildren);
+  });
 
   return IPC_OK();
 }
 
 void ContentParent::RegisterRemoteWorkerActor() { ++mRemoteWorkerActors; }
 
 void ContentParent::UnregisterRemoveWorkerActor() {
   MOZ_ASSERT(NS_IsMainThread());
@@ -5960,26 +5933,21 @@ mozilla::ipc::IPCResult ContentParent::R
 
   // Check if the transaction is valid.
   if (!aContext->Canonical()->ValidateTransaction(aTransaction, this)) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Error,
             ("ParentIPC: Trying to run invalid transaction."));
     return IPC_FAIL_NO_REASON(this);
   }
 
-  for (auto iter = aContext->Group()->ContentParentsIter(); !iter.Done();
-       iter.Next()) {
-    auto* entry = iter.Get();
-    ContentParent* parent = entry->GetKey();
-    if (parent != this) {
-      Unused << parent->SendCommitBrowsingContextTransaction(
-          aContext, aTransaction,
-          aContext->Canonical()->GetFieldEpochsForChild(parent));
-    }
-  }
+  aContext->Group()->EachOtherParent(this, [&](ContentParent* aParent) {
+    Unused << aParent->SendCommitBrowsingContextTransaction(
+        aContext, aTransaction,
+        aContext->Canonical()->GetFieldEpochsForChild(aParent));
+  });
 
   aTransaction.Apply(aContext, this);
   aContext->Canonical()->SetFieldEpochsForChild(this, aEpochs);
 
   return IPC_OK();
 }
 }  // namespace dom
 }  // namespace mozilla