SharedWorkerManager.h (5374B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_dom_SharedWorkerManager_h 8 #define mozilla_dom_SharedWorkerManager_h 9 10 #include "SharedWorkerParent.h" 11 #include "mozilla/dom/RemoteWorkerController.h" 12 #include "mozilla/dom/quota/CheckedUnsafePtr.h" 13 #include "nsISupportsImpl.h" 14 #include "nsTArray.h" 15 16 class nsIPrincipal; 17 18 namespace mozilla::dom { 19 20 class UniqueMessagePortId; 21 class RemoteWorkerData; 22 class SharedWorkerManager; 23 class SharedWorkerService; 24 25 // Main-thread only object that keeps a manager and the service alive. 26 // When the last SharedWorkerManagerHolder is released, the corresponding 27 // manager unregisters itself from the service and terminates the worker. 28 class SharedWorkerManagerHolder final 29 : public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> { 30 public: 31 NS_INLINE_DECL_REFCOUNTING(SharedWorkerManagerHolder); 32 33 SharedWorkerManagerHolder(SharedWorkerManager* aManager, 34 SharedWorkerService* aService); 35 36 SharedWorkerManager* Manager() const { return mManager; } 37 38 SharedWorkerService* Service() const { return mService; } 39 40 private: 41 ~SharedWorkerManagerHolder(); 42 43 const RefPtr<SharedWorkerManager> mManager; 44 const RefPtr<SharedWorkerService> mService; 45 }; 46 47 // Thread-safe wrapper for SharedWorkerManagerHolder. 48 class SharedWorkerManagerWrapper final { 49 public: 50 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerManagerWrapper); 51 52 explicit SharedWorkerManagerWrapper( 53 already_AddRefed<SharedWorkerManagerHolder> aHolder); 54 55 SharedWorkerManager* Manager() const { return mHolder->Manager(); } 56 57 private: 58 ~SharedWorkerManagerWrapper(); 59 60 RefPtr<SharedWorkerManagerHolder> mHolder; 61 }; 62 63 /** 64 * PBackground instance that corresponds to a single logical Shared Worker that 65 * exists somewhere in the process tree. Referenced/owned by multiple 66 * SharedWorkerParent instances on the PBackground thread. Holds/owns a single 67 * RemoteWorkerController to interact with the actual shared worker thread, 68 * wherever it is located. Creates the RemoteWorkerController via 69 * RemoteWorkerController::Create which uses RemoteWorkerManager::Launch under 70 * the hood. 71 */ 72 class SharedWorkerManager final : public RemoteWorkerObserver { 73 public: 74 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerManager, override); 75 76 // Called on main-thread thread methods 77 78 static already_AddRefed<SharedWorkerManagerHolder> Create( 79 SharedWorkerService* aService, nsIEventTarget* aPBackgroundEventTarget, 80 const RemoteWorkerData& aData, nsIPrincipal* aLoadingPrincipal, 81 const OriginAttributes& aEffectiveStoragePrincipalAttrs); 82 83 // Returns a holder if this manager matches. The holder blocks the shutdown of 84 // the manager. 85 already_AddRefed<SharedWorkerManagerHolder> MatchOnMainThread( 86 SharedWorkerService* aService, const RemoteWorkerData& aData, 87 nsIURI* aScriptURL, nsIPrincipal* aLoadingPrincipal, 88 const OriginAttributes& aEffectiveStoragePrincipalAttrs, 89 bool* aMatchNameButNotOptions); 90 91 // RemoteWorkerObserver 92 93 void CreationFailed() override; 94 95 void CreationSucceeded() override; 96 97 void ErrorReceived(const ErrorValue& aValue) override; 98 99 void LockNotified(bool aCreated) final; 100 101 void WebTransportNotified(bool aCreated) final; 102 103 void Terminated() override; 104 105 // Called on PBackground thread methods 106 107 bool MaybeCreateRemoteWorker(const RemoteWorkerData& aData, 108 uint64_t aWindowID, 109 UniqueMessagePortId& aPortIdentifier, 110 base::ProcessId aProcessId); 111 112 void AddActor(SharedWorkerParent* aParent); 113 114 void RemoveActor(SharedWorkerParent* aParent); 115 116 void UpdateSuspend(); 117 118 void UpdateFrozen(); 119 120 bool IsSecureContext() const; 121 122 void Terminate(); 123 124 // Called on main-thread only. 125 126 void RegisterHolder(SharedWorkerManagerHolder* aHolder); 127 128 void UnregisterHolder(SharedWorkerManagerHolder* aHolder); 129 130 private: 131 SharedWorkerManager(nsIEventTarget* aPBackgroundEventTarget, 132 const RemoteWorkerData& aData, 133 nsIPrincipal* aLoadingPrincipal, 134 const OriginAttributes& aEffectiveStoragePrincipalAttrs); 135 136 ~SharedWorkerManager(); 137 138 nsCOMPtr<nsIEventTarget> mPBackgroundEventTarget; 139 140 nsCOMPtr<nsIPrincipal> mLoadingPrincipal; 141 const nsCString mDomain; 142 const OriginAttributes mEffectiveStoragePrincipalAttrs; 143 const nsCOMPtr<nsIURI> mResolvedScriptURL; 144 const WorkerOptions mWorkerOptions; 145 const bool mIsSecureContext; 146 bool mSuspended; 147 bool mFrozen; 148 uint32_t mLockCount = 0; 149 uint32_t mWebTransportCount = 0; 150 151 // Raw pointers because SharedWorkerParent unregisters itself in 152 // ActorDestroy(). 153 nsTArray<CheckedUnsafePtr<SharedWorkerParent>> mActors; 154 155 RefPtr<RemoteWorkerController> mRemoteWorkerController; 156 157 // Main-thread only. Raw Pointers because holders keep the manager alive and 158 // they unregister themselves in their DTOR. 159 nsTArray<CheckedUnsafePtr<SharedWorkerManagerHolder>> mHolders; 160 }; 161 162 } // namespace mozilla::dom 163 164 #endif // mozilla_dom_SharedWorkerManager_h