RemoteWorkerOp.h (3837B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef mozilla_dom_RemoteWorkerOp_h 6 #define mozilla_dom_RemoteWorkerOp_h 7 8 #include "mozilla/RefPtr.h" 9 #include "mozilla/Variant.h" 10 #include "mozilla/dom/WorkerPrivate.h" 11 12 namespace mozilla::dom { 13 14 class RemoteWorkerChild; 15 class RemtoeWorkerNonfLifeCycleOpControllerChild; 16 class RemoteWorkerOp; 17 // class RemoteWorkerNonLifeCycleOpControllerChild; 18 19 namespace remoteworker { 20 21 struct WorkerPrivateAccessibleState { 22 ~WorkerPrivateAccessibleState(); 23 RefPtr<WorkerPrivate> mWorkerPrivate; 24 }; 25 26 // Initial state, mWorkerPrivate is initially null but will be initialized on 27 // the main thread by ExecWorkerOnMainThread when the WorkerPrivate is 28 // created. The state will transition to Running or Canceled, also from the 29 // main thread. 30 struct Pending : WorkerPrivateAccessibleState { 31 nsTArray<RefPtr<RemoteWorkerOp>> mPendingOps; 32 }; 33 34 // Running, with the state transition happening on the main thread as a result 35 // of the worker successfully processing our initialization runnable, 36 // indicating that top-level script execution successfully completed. Because 37 // all of our state transitions happen on the main thread and are posed in 38 // terms of the main thread's perspective of the worker's state, it's very 39 // possible for us to skip directly from Pending to Canceled because we decide 40 // to cancel/terminate the worker prior to it finishing script loading or 41 // reporting back to us. 42 struct Running : WorkerPrivateAccessibleState {}; 43 44 // Cancel() has been called on the WorkerPrivate on the main thread by a 45 // TerminationOp, top-level script evaluation has failed and canceled the 46 // worker, or in the case of a SharedWorker, close() has been called on 47 // the global scope by content code and the worker has advanced to the 48 // Canceling state. (Dedicated Workers can also self close, but they will 49 // never be RemoteWorkers. Although a SharedWorker can own DedicatedWorkers.) 50 // Browser shutdown will result in a TerminationOp thanks to use of a shutdown 51 // blocker in the parent, so the RuntimeService shouldn't get involved, but we 52 // would also handle that case acceptably too. 53 // 54 // Because worker self-closing is still handled by dispatching a runnable to 55 // the main thread to effectively call WorkerPrivate::Cancel(), there isn't 56 // a race between a worker deciding to self-close and our termination ops. 57 // 58 // In this state, we have dropped the reference to the WorkerPrivate and will 59 // no longer be dispatching runnables to the worker. We wait in this state 60 // until the termination lambda is invoked letting us know that the worker has 61 // entirely shutdown and we can advanced to the Killed state. 62 struct Canceled {}; 63 64 // The worker termination lambda has been invoked and we know the Worker is 65 // entirely shutdown. (Inherently it is possible for us to advance to this 66 // state while the nsThread for the worker is still in the process of 67 // shutting down, but no more worker code will run on it.) 68 // 69 // This name is chosen to match the Worker's own state model. 70 struct Killed {}; 71 72 using RemoteWorkerState = Variant<Pending, Running, Canceled, Killed>; 73 74 } // namespace remoteworker 75 76 class RemoteWorkerOp { 77 public: 78 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING 79 80 virtual ~RemoteWorkerOp() = default; 81 82 virtual bool MaybeStart(RemoteWorkerChild* aOwner, 83 remoteworker::RemoteWorkerState& aState) = 0; 84 85 virtual void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) = 0; 86 87 virtual void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, 88 remoteworker::RemoteWorkerState& aState) = 0; 89 90 virtual void Cancel() = 0; 91 }; 92 93 } // namespace mozilla::dom 94 95 #endif