RemoteWorkerManager.h (4516B)
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_RemoteWorkerManager_h 8 #define mozilla_dom_RemoteWorkerManager_h 9 10 #include "base/process.h" 11 #include "mozilla/RefPtr.h" 12 #include "mozilla/dom/ContentParent.h" 13 #include "mozilla/dom/RemoteWorkerTypes.h" 14 #include "mozilla/dom/WorkerPrivate.h" // WorkerKind enum 15 #include "nsISupportsImpl.h" 16 #include "nsTArray.h" 17 18 namespace mozilla::dom { 19 20 class RemoteWorkerController; 21 class RemoteWorkerServiceParent; 22 class RemoteWorkerNonLifeCycleOpControllerParent; 23 24 /** 25 * PBackground instance that keeps tracks of RemoteWorkerServiceParent actors 26 * (1 per process, including the main process). Decides which 27 * RemoteWorkerServerParent to use internally via SelectTargetActor in order to 28 * select a BackgroundParent manager on which to create a RemoteWorkerParent. 29 */ 30 class RemoteWorkerManager final { 31 public: 32 NS_INLINE_DECL_REFCOUNTING(RemoteWorkerManager) 33 34 static already_AddRefed<RemoteWorkerManager> GetOrCreate(); 35 36 void RegisterActor(RemoteWorkerServiceParent* aActor); 37 38 void UnregisterActor(RemoteWorkerServiceParent* aActor); 39 40 void Launch(RemoteWorkerController* aController, 41 const RemoteWorkerData& aData, base::ProcessId aProcessId); 42 43 static bool MatchRemoteType(const nsACString& processRemoteType, 44 const nsACString& workerRemoteType); 45 46 /** 47 * Get the child process RemoteType where a RemoteWorker should be 48 * launched. 49 */ 50 static Result<nsCString, nsresult> GetRemoteType( 51 const nsCOMPtr<nsIPrincipal>& aPrincipal, WorkerKind aWorkerKind); 52 53 static bool HasExtensionPrincipal(const RemoteWorkerData& aData); 54 55 private: 56 RemoteWorkerManager(); 57 ~RemoteWorkerManager(); 58 59 struct TargetActorAndKeepAlive { 60 RefPtr<RemoteWorkerServiceParent> mActor; 61 UniqueThreadsafeContentParentKeepAlive mKeepAlive; 62 }; 63 64 TargetActorAndKeepAlive SelectTargetActor(const RemoteWorkerData& aData, 65 base::ProcessId aProcessId); 66 67 TargetActorAndKeepAlive SelectTargetActorInternal( 68 const RemoteWorkerData& aData, base::ProcessId aProcessId) const; 69 70 void LaunchInternal(RemoteWorkerController* aController, 71 RemoteWorkerServiceParent* aTargetActor, 72 UniqueThreadsafeContentParentKeepAlive&& aKeepAlive, 73 const RemoteWorkerData& aData); 74 75 using LaunchProcessPromise = 76 MozPromise<TargetActorAndKeepAlive, nsresult, true>; 77 RefPtr<LaunchProcessPromise> LaunchNewContentProcess( 78 const RemoteWorkerData& aData); 79 80 void AsyncCreationFailed(RemoteWorkerController* aController); 81 82 // Iterate through all RemoteWorkerServiceParent actors with the given 83 // remoteType, starting from the actor related to a child process with pid 84 // aProcessId if needed and available or from a random index otherwise (as if 85 // iterating through a circular array). 86 // 87 // aCallback should be a invokable object with a function signature of 88 // bool (RemoteWorkerServiceParent*, RefPtr<ContentParent>&&) 89 // 90 // aCallback is called with the actor and corresponding ContentParent, should 91 // return false to abort iteration before all actors have been traversed (e.g. 92 // if the desired actor is found), and must not mutate mChildActors (which 93 // shouldn't be an issue because this function is const). aCallback also 94 // doesn't need to worry about proxy-releasing the ContentParent if it isn't 95 // moved out of the parameter. 96 template <typename Callback> 97 void ForEachActor(Callback&& aCallback, const nsACString& aRemoteType, 98 Maybe<base::ProcessId> aProcessId = Nothing()) const; 99 100 // The list of existing RemoteWorkerServiceParent actors for child processes. 101 // Raw pointers because RemoteWorkerServiceParent actors unregister themselves 102 // when destroyed. 103 // XXX For Fission, where we could have a lot of child actors, should we maybe 104 // instead keep either a hash table (PID->actor) or perhaps store the actors 105 // in order, sorted by PID, to avoid linear lookup times? 106 nsTArray<RemoteWorkerServiceParent*> mChildActors; 107 RemoteWorkerServiceParent* mParentActor; 108 }; 109 110 } // namespace mozilla::dom 111 112 #endif // mozilla_dom_RemoteWorkerManager_h