Bug 1584007 - initial implementation of FutureClientSourceParent r=dom-workers-and-storage-reviewers,mattwoodrow,asuth
authorPerry Jiang <perry@mozilla.com>
Tue, 24 Mar 2020 15:16:42 +0000
changeset 520464 24deb3d467831a8e74ee8addf3c53119ca019dd3
parent 520463 5e79a0bcc9155c064dda7edf73cf82cff2515c2c
child 520465 ac2765b4b4ec5d18ea22edefbdc3095893855f9c
push id37251
push usermalexandru@mozilla.com
push dateThu, 26 Mar 2020 09:33:08 +0000
treeherdermozilla-central@3e5a7430c8d7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-workers-and-storage-reviewers, mattwoodrow, asuth
bugs1584007
milestone76.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 1584007 - initial implementation of FutureClientSourceParent r=dom-workers-and-storage-reviewers,mattwoodrow,asuth Also implements SourceTableEntry and nsIDHasher to switch ClientManagerService's nsDataHashTable to a mozilla::HashMap<nsID, SourceTableEntry> in following changesets. Differential Revision: https://phabricator.services.mozilla.com/D66144
dom/clients/manager/ClientManagerService.cpp
dom/clients/manager/ClientManagerService.h
dom/clients/manager/moz.build
--- a/dom/clients/manager/ClientManagerService.cpp
+++ b/dom/clients/manager/ClientManagerService.cpp
@@ -102,16 +102,20 @@ RefPtr<GenericPromise> OnShutdown() {
 
   MOZ_ALWAYS_SUCCEEDS(SystemGroup::Dispatch(TaskCategory::Other, r.forget()));
 
   return ref;
 }
 
 }  // anonymous namespace
 
+ClientManagerService::FutureClientSourceParent::FutureClientSourceParent(
+    const IPCClientInfo& aClientInfo)
+    : mPrincipalInfo(aClientInfo.principalInfo()) {}
+
 ClientManagerService::ClientManagerService() : mShutdown(false) {
   AssertIsOnBackgroundThread();
 
   // Only register one shutdown handler at a time.  If a previous service
   // instance did this, but shutdown has not come, then we can avoid
   // doing it again.
   if (!sClientManagerServiceShutdownRegistered) {
     sClientManagerServiceShutdownRegistered = true;
--- a/dom/clients/manager/ClientManagerService.h
+++ b/dom/clients/manager/ClientManagerService.h
@@ -1,17 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 #ifndef _mozilla_dom_ClientManagerService_h
 #define _mozilla_dom_ClientManagerService_h
 
+#include "ClientHandleParent.h"
 #include "ClientOpPromise.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/HashTable.h"
+#include "mozilla/MozPromise.h"
+#include "mozilla/Variant.h"
 #include "nsDataHashtable.h"
 
 namespace mozilla {
 
 namespace ipc {
 
 class PrincipalInfo;
 
@@ -23,16 +28,65 @@ class ClientManagerParent;
 class ClientSourceParent;
 class ClientHandleParent;
 class ContentParent;
 
 // Define a singleton service to manage client activity throughout the
 // browser.  This service runs on the PBackground thread.  To interact
 // it with it please use the ClientManager and ClientHandle classes.
 class ClientManagerService final {
+  // Placeholder type that represents a ClientSourceParent that may be created
+  // in the future (e.g. while a redirect chain is being resolved).
+  //
+  // Each FutureClientSourceParent has a promise that callbacks may be chained
+  // to; the promise will be resolved when the associated ClientSourceParent is
+  // created or rejected when it's known that it'll never be created.
+  class FutureClientSourceParent {
+   public:
+    explicit FutureClientSourceParent(const IPCClientInfo& aClientInfo);
+
+    const mozilla::ipc::PrincipalInfo& PrincipalInfo() const {
+      return mPrincipalInfo;
+    }
+
+    already_AddRefed<SourcePromise> Promise() {
+      return mPromiseHolder.Ensure(__func__);
+    }
+
+    void ResolvePromiseIfExists(ClientSourceParent* aSource) {
+      MOZ_ASSERT(aSource);
+      mPromiseHolder.ResolveIfExists(aSource, __func__);
+    }
+
+    void RejectPromiseIfExists(const CopyableErrorResult& aRv) {
+      MOZ_ASSERT(aRv.Failed());
+      mPromiseHolder.RejectIfExists(aRv, __func__);
+    }
+
+   private:
+    const mozilla::ipc::PrincipalInfo mPrincipalInfo;
+    MozPromiseHolder<SourcePromise> mPromiseHolder;
+  };
+
+  using SourceTableEntry =
+      Variant<FutureClientSourceParent, ClientSourceParent*>;
+
+  struct nsIDHasher {
+    using Key = nsID;
+    using Lookup = Key;
+
+    static HashNumber hash(const Lookup& aLookup) {
+      return HashBytes(&aLookup, sizeof(Lookup));
+    }
+
+    static bool match(const Key& aKey, const Lookup& aLookup) {
+      return aKey.Equals(aLookup);
+    }
+  };
+
   // Store the ClientSourceParent objects in a hash table.  We want to
   // optimize for insertion, removal, and lookup by UUID.
   nsDataHashtable<nsIDHashKey, ClientSourceParent*> mSourceTable;
 
   // The set of handles waiting for their corresponding ClientSourceParent
   // to be created.
   nsDataHashtable<nsIDHashKey, nsTArray<ClientHandleParent*>> mPendingHandles;
 
--- a/dom/clients/manager/moz.build
+++ b/dom/clients/manager/moz.build
@@ -2,16 +2,17 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
   'ClientChannelHelper.h',
   'ClientHandle.h',
+  'ClientHandleParent.h',
   'ClientInfo.h',
   'ClientIPCUtils.h',
   'ClientManager.h',
   'ClientManagerActors.h',
   'ClientManagerService.h',
   'ClientOpPromise.h',
   'ClientSource.h',
   'ClientState.h',