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_RemoteWorkerChild_h 8 #define mozilla_dom_RemoteWorkerChild_h 9 10 #include "nsCOMPtr.h" 11 #include "nsISupportsImpl.h" 12 #include "nsTArray.h" 13 14 #include "mozilla/DataMutex.h" 15 #include "mozilla/MozPromise.h" 16 #include "mozilla/RefPtr.h" 17 #include "mozilla/ThreadBound.h" 18 #include "mozilla/ThreadSafeWeakPtr.h" 19 #include "mozilla/dom/PRemoteWorkerChild.h" 20 #include "mozilla/dom/ServiceWorkerOpArgs.h" 21 22 class nsISerialEventTarget; 23 class nsIConsoleReportCollector; 24 25 namespace mozilla { 26 namespace dom { 27 28 class ErrorValue; 29 class FetchEventOpProxyChild; 30 class RemoteWorkerData; 31 class ServiceWorkerOp; 32 class UniqueMessagePortId; 33 class WeakWorkerRef; 34 class WorkerErrorReport; 35 class WorkerPrivate; 36 37 class RemoteWorkerChild final 38 : public SupportsThreadSafeWeakPtr<RemoteWorkerChild>, 39 public PRemoteWorkerChild { 40 friend class FetchEventOpProxyChild; 41 friend class PRemoteWorkerChild; 42 friend class ServiceWorkerOp; 43 44 public: 45 MOZ_DECLARE_THREADSAFEWEAKREFERENCE_TYPENAME(RemoteWorkerChild) 46 47 MOZ_DECLARE_REFCOUNTED_TYPENAME(RemoteWorkerChild) 48 49 explicit RemoteWorkerChild(const RemoteWorkerData& aData); 50 51 ~RemoteWorkerChild(); 52 53 nsISerialEventTarget* GetOwningEventTarget() const; 54 55 void ExecWorker(const RemoteWorkerData& aData); 56 57 void ErrorPropagationOnMainThread(const WorkerErrorReport* aReport, 58 bool aIsErrorEvent); 59 60 void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter); 61 62 void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate, 63 UniqueMessagePortId& aPortIdentifier); 64 65 RefPtr<GenericNonExclusivePromise> GetTerminationPromise(); 66 67 RefPtr<GenericPromise> MaybeSendSetServiceWorkerSkipWaitingFlag(); 68 69 private: 70 class InitializeWorkerRunnable; 71 72 class Op; 73 class SharedWorkerOp; 74 75 struct WorkerPrivateAccessibleState { 76 ~WorkerPrivateAccessibleState(); 77 RefPtr<WorkerPrivate> mWorkerPrivate; 78 }; 79 80 struct Pending : WorkerPrivateAccessibleState { 81 nsTArray<RefPtr<Op>> mPendingOps; 82 }; 83 84 struct PendingTerminated {}; 85 86 struct Running : WorkerPrivateAccessibleState { 87 ~Running(); 88 RefPtr<WeakWorkerRef> mWorkerRef; 89 }; 90 91 struct Terminated {}; 92 93 using State = Variant<Pending, Running, PendingTerminated, Terminated>; 94 95 DataMutex<State> mState; 96 97 class Op { 98 public: 99 NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING 100 101 virtual ~Op() = default; 102 103 virtual bool MaybeStart(RemoteWorkerChild* aOwner, State& aState) = 0; 104 105 virtual void Cancel() = 0; 106 }; 107 108 void ActorDestroy(ActorDestroyReason) override; 109 110 mozilla::ipc::IPCResult RecvExecOp(RemoteWorkerOp&& aOp); 111 112 mozilla::ipc::IPCResult RecvExecServiceWorkerOp( 113 ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve); 114 115 PFetchEventOpProxyChild* AllocPFetchEventOpProxyChild( 116 const ServiceWorkerFetchEventOpArgs& aArgs); 117 118 mozilla::ipc::IPCResult RecvPFetchEventOpProxyConstructor( 119 PFetchEventOpProxyChild* aActor, 120 const ServiceWorkerFetchEventOpArgs& aArgs) override; 121 122 bool DeallocPFetchEventOpProxyChild(PFetchEventOpProxyChild* aActor); 123 124 nsresult ExecWorkerOnMainThread(RemoteWorkerData&& aData); 125 126 void InitializeOnWorker(); 127 128 void ShutdownOnWorker(); 129 130 void CreationSucceededOnAnyThread(); 131 132 void CreationFailedOnAnyThread(); 133 134 void CreationSucceededOrFailedOnAnyThread(bool aDidCreationSucceed); 135 136 void CloseWorkerOnMainThread(State& aState); 137 138 void ErrorPropagation(const ErrorValue& aValue); 139 140 void ErrorPropagationDispatch(nsresult aError); 141 142 void TransitionStateToPendingTerminated(State& aState); 143 144 void TransitionStateToRunning(already_AddRefed<WorkerPrivate> aWorkerPrivate, 145 already_AddRefed<WeakWorkerRef> aWorkerRef); 146 147 void TransitionStateToTerminated(); 148 149 void TransitionStateToTerminated(State& aState); 150 151 void CancelAllPendingOps(State& aState); 152 153 void MaybeStartOp(RefPtr<Op>&& aOp); 154 155 const bool mIsServiceWorker; 156 const nsCOMPtr<nsISerialEventTarget> mOwningEventTarget; 157 158 // Touched on main-thread only. 159 nsTArray<uint64_t> mWindowIDs; 160 161 struct LauncherBoundData { 162 bool mIPCActive = true; 163 MozPromiseHolder<GenericNonExclusivePromise> mTerminationPromise; 164 }; 165 166 ThreadBound<LauncherBoundData> mLauncherData; 167 }; 168 169 } // namespace dom 170 } // namespace mozilla 171 172 #endif // mozilla_dom_RemoteWorkerChild_h 173