Backed out changeset 9d8b4c0b99ed (bug 1945683) for causing btime failures. CLOSED...
[gecko.git] / dom / workers / remoteworkers / RemoteWorkerController.h
blobc60ce238f929a9dca3866e5de10031c465002ee9
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/. */
7 #ifndef mozilla_dom_RemoteWorkerController_h
8 #define mozilla_dom_RemoteWorkerController_h
10 #include "nsISupportsImpl.h"
11 #include "nsTArray.h"
13 #include "mozilla/RefPtr.h"
14 #include "mozilla/UniquePtr.h"
15 #include "mozilla/dom/DOMTypes.h"
16 #include "mozilla/dom/ServiceWorkerOpArgs.h"
17 #include "mozilla/dom/ServiceWorkerOpPromise.h"
18 #include "mozilla/dom/SharedWorkerOpArgs.h"
20 namespace mozilla::dom {
22 /* Here's a graph about this remote workers are spawned.
24 * _________________________________ | ________________________________
25 * | | | | |
26 * | Parent process | IPC | Creation of Process X |
27 * | PBackground thread | | | |
28 * | | | | [RemoteWorkerService::Init()] |
29 * | | | | | |
30 * | | | | | (1) |
31 * | [RemoteWorkerManager:: (2) | | | V |
32 * | RegisterActor()]<-------- [new RemoteWorkerServiceChild] |
33 * | | | | |
34 * | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | |________________________________|
35 * | | |
36 * | new SharedWorker/ServiceWorker | |
37 * | | ^ | IPC
38 * | (3) | (4)| |
39 * | V | | |
40 * | [RemoteWorkerController:: | |
41 * | | Create(data)] | |
42 * | | (5) | |
43 * | V | |
44 * | [RemoteWorkerManager::Launch()] | |
45 * | | | IPC _____________________________
46 * | | (6) | | | |
47 * | | | | Selected content process |
48 * | V | (7) | |
49 * | [SendPRemoteWorkerConstructor()]--------->[new RemoteWorkerChild()] |
50 * | | | | | | |
51 * | | (8) | | | | |
52 * | V | | | V |
53 * | [RemoteWorkerController-> | | | RemoteWorkerChild->Exec() |
54 * | | SetControllerActor()] | | |_____________________________|
55 * | (9) | | IPC
56 * | V | |
57 * | [RemoteWorkerObserver-> | |
58 * | CreationCompleted()] | |
59 * |_________________________________| |
60 * |
62 * 1. When a new process starts, it creates a RemoteWorkerService singleton.
63 * This service creates a new thread (Worker Launcher) and from there, it
64 * starts a PBackground RemoteWorkerServiceChild actor.
65 * 2. On the parent process, PBackground thread, RemoteWorkerServiceParent
66 * actors are registered into the RemoteWorkerManager service.
68 * 3. At some point, a SharedWorker or a ServiceWorker must be executed.
69 * RemoteWorkerController::Create() is used to start the launching. This
70 * method must be called on the parent process, on the PBackground thread.
71 * 4. RemoteWorkerController object is immediately returned to the caller. Any
72 * operation done with this controller object will be stored in a queue,
73 * until the launching is correctly executed.
74 * 5. RemoteWorkerManager has the list of active RemoteWorkerServiceParent
75 * actors. From them, it picks one.
76 * In case we don't have any content process to select, a new one is
77 * spawned. If this happens, the operation is suspended until a new
78 * RemoteWorkerServiceParent is registered.
79 * 6. RemoteWorkerServiceParent is used to create a RemoteWorkerParent.
80 * 7. RemoteWorkerChild is created on a selected process and it executes the
81 * WorkerPrivate.
82 * 8. The RemoteWorkerParent actor is passed to the RemoteWorkerController.
83 * 9. RemoteWorkerController now is ready to continue and it called
84 * RemoteWorkerObserver to inform that the operation is completed.
85 * In case there were pending operations, they are now executed.
88 class ErrorValue;
89 class FetchEventOpParent;
90 class RemoteWorkerControllerParent;
91 class RemoteWorkerData;
92 class RemoteWorkerManager;
93 class RemoteWorkerNonLifeCycleOpControllerParent;
94 class RemoteWorkerParent;
96 class RemoteWorkerObserver {
97 public:
98 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
100 virtual void CreationFailed() = 0;
102 virtual void CreationSucceeded() = 0;
104 virtual void ErrorReceived(const ErrorValue& aValue) = 0;
106 virtual void LockNotified(bool aCreated) = 0;
108 virtual void WebTransportNotified(bool aCreated) = 0;
110 virtual void Terminated() = 0;
114 * PBackground instance created by static RemoteWorkerController::Create that
115 * builds on RemoteWorkerManager. Interface to control the remote worker as well
116 * as receive events via the RemoteWorkerObserver interface that the owner
117 * (SharedWorkerManager in this case) must implement to hear about errors,
118 * termination, and whether the initial spawning succeeded/failed.
120 * Its methods may be called immediately after creation even though the worker
121 * is created asynchronously; an internal operation queue makes this work.
122 * Communicates with the remote worker via owned RemoteWorkerParent over
123 * PRemoteWorker protocol.
125 class RemoteWorkerController final {
126 friend class RemoteWorkerControllerParent;
127 friend class RemoteWorkerManager;
128 friend class RemoteWorkerParent;
129 friend class RemoteWorkerNonLifeCycleOpControllerParent;
131 public:
132 NS_INLINE_DECL_REFCOUNTING(RemoteWorkerController)
134 static already_AddRefed<RemoteWorkerController> Create(
135 const RemoteWorkerData& aData, RemoteWorkerObserver* aObserver,
136 base::ProcessId = 0);
138 void AddWindowID(uint64_t aWindowID);
140 void RemoveWindowID(uint64_t aWindowID);
142 void AddPortIdentifier(const MessagePortIdentifier& aPortIdentifier);
144 void Terminate();
146 void Suspend();
148 void Resume();
150 void Freeze();
152 void Thaw();
154 RefPtr<ServiceWorkerOpPromise> ExecServiceWorkerOp(
155 ServiceWorkerOpArgs&& aArgs);
157 RefPtr<ServiceWorkerFetchEventOpPromise> ExecServiceWorkerFetchEventOp(
158 const ParentToParentServiceWorkerFetchEventOpArgs& aArgs,
159 RefPtr<FetchEventOpParent> aReal);
161 RefPtr<GenericPromise> SetServiceWorkerSkipWaitingFlag() const;
163 bool IsTerminated() const;
165 void NotifyWebTransport(bool aCreated);
167 private:
168 RemoteWorkerController(const RemoteWorkerData& aData,
169 RemoteWorkerObserver* aObserver);
171 ~RemoteWorkerController();
173 void SetWorkerActor(RemoteWorkerParent* aActor);
175 void NoteDeadWorkerActor();
177 void ErrorPropagation(const ErrorValue& aValue);
179 void NotifyLock(bool aCreated);
181 void WorkerTerminated();
183 void Shutdown();
185 void CreationFailed();
187 void CreationSucceeded();
189 void CancelAllPendingOps();
191 template <typename... Args>
192 void MaybeStartSharedWorkerOp(Args&&... aArgs);
194 void NoteDeadWorker();
196 RefPtr<RemoteWorkerObserver> mObserver;
197 RefPtr<RemoteWorkerParent> mActor;
198 RefPtr<RemoteWorkerNonLifeCycleOpControllerParent> mNonLifeCycleOpController;
200 enum {
201 ePending,
202 eReady,
203 eTerminated,
204 } mState;
206 const bool mIsServiceWorker;
209 * `PendingOp` is responsible for encapsulating logic for starting and
210 * canceling pending remote worker operations, as this logic may vary
211 * depending on the type of the remote worker and the type of the operation.
213 class PendingOp {
214 public:
215 PendingOp() = default;
217 PendingOp(const PendingOp&) = delete;
219 PendingOp& operator=(const PendingOp&) = delete;
221 virtual ~PendingOp() = default;
224 * Returns `true` if execution has started or the operation is moot and
225 * doesn't need to be queued, `false` if execution hasn't started and the
226 * operation should be queued. In general, operations should only return
227 * false when a remote worker is first starting up. Operations may also
228 * somewhat non-intuitively return true without doing anything if the worker
229 * has already been told to shutdown.
231 * Starting execution may depend the state of `aOwner.`
233 virtual bool MaybeStart(RemoteWorkerController* const aOwner) = 0;
236 * Invoked if the operation will never have MaybeStart() called again
237 * because the RemoteWorkerController has terminated (or will never start).
238 * This should be used by PendingOps to clean up any resources they own and
239 * may also be called internally by their MaybeStart() methods if they
240 * determine the worker has been terminated. This should be idempotent.
242 virtual void Cancel() = 0;
245 class PendingSharedWorkerOp final : public PendingOp {
246 public:
247 enum Type {
248 eTerminate,
249 eSuspend,
250 eResume,
251 eFreeze,
252 eThaw,
253 ePortIdentifier,
254 eAddWindowID,
255 eRemoveWindowID,
258 explicit PendingSharedWorkerOp(Type aType, uint64_t aWindowID = 0);
260 explicit PendingSharedWorkerOp(
261 const MessagePortIdentifier& aPortIdentifier);
263 ~PendingSharedWorkerOp();
265 bool MaybeStart(RemoteWorkerController* const aOwner) override;
267 void Cancel() override;
269 private:
270 const Type mType;
271 const MessagePortIdentifier mPortIdentifier;
272 const uint64_t mWindowID = 0;
273 bool mCompleted = false;
276 class PendingServiceWorkerOp final : public PendingOp {
277 public:
278 PendingServiceWorkerOp(ServiceWorkerOpArgs&& aArgs,
279 RefPtr<ServiceWorkerOpPromise::Private> aPromise);
281 ~PendingServiceWorkerOp();
283 bool MaybeStart(RemoteWorkerController* const aOwner) override;
285 void Cancel() override;
287 private:
288 ServiceWorkerOpArgs mArgs;
289 RefPtr<ServiceWorkerOpPromise::Private> mPromise;
293 * Custom pending op type to deal with the complexities of FetchEvents having
294 * their own actor.
296 * FetchEvent Ops have their own actor type because their lifecycle is more
297 * complex than IPDL's async return value mechanism allows. Additionally,
298 * its IPC struct potentially has to serialize RemoteLazyStreams which
299 * requires us to hold an nsIInputStream when at rest and serialize it when
300 * eventually sending.
302 class PendingSWFetchEventOp final : public PendingOp {
303 public:
304 PendingSWFetchEventOp(
305 const ParentToParentServiceWorkerFetchEventOpArgs& aArgs,
306 RefPtr<ServiceWorkerFetchEventOpPromise::Private> aPromise,
307 RefPtr<FetchEventOpParent>&& aReal);
309 ~PendingSWFetchEventOp();
311 bool MaybeStart(RemoteWorkerController* const aOwner) override;
313 void Cancel() override;
315 private:
316 ParentToParentServiceWorkerFetchEventOpArgs mArgs;
317 RefPtr<ServiceWorkerFetchEventOpPromise::Private> mPromise;
318 RefPtr<FetchEventOpParent> mReal;
319 nsCOMPtr<nsIInputStream> mBodyStream;
322 nsTArray<UniquePtr<PendingOp>> mPendingOps;
325 } // namespace mozilla::dom
327 #endif // mozilla_dom_RemoteWorkerController_h