From 3f11cda5a49c7908b6931d59b00e4a250cc54a2e Mon Sep 17 00:00:00 2001 From: Sandor Molnar Date: Thu, 27 Jun 2024 13:02:33 +0300 Subject: [PATCH] Backed out 5 changesets (bug 1672493) for causing serviceworker related perma failures. CLOSED TREE Backed out changeset a38e64bdda2c (bug 1672493) Backed out changeset b4e568bfb9c7 (bug 1672493) Backed out changeset 4f1ee5c1e441 (bug 1672493) Backed out changeset e05276c441ef (bug 1672493) Backed out changeset e80cf5cf2fe5 (bug 1672493) --- dom/serviceworkers/FetchEventOpParent.cpp | 1 - .../FetchEventOpProxyParent.cpp | 2 - dom/serviceworkers/ServiceWorkerOp.cpp | 86 ++----- dom/serviceworkers/ServiceWorkerOp.h | 11 +- dom/workers/WorkerPrivate.cpp | 34 +-- dom/workers/WorkerPrivate.h | 21 +- dom/workers/remoteworkers/PRemoteWorker.ipdl | 45 +++- ...PRemoteWorkerNonLifeCycleOpController.ipdl | 31 --- .../remoteworkers/PRemoteWorkerService.ipdl | 4 +- .../remoteworkers/RemoteWorkerChild.cpp | 236 +++++++++++++++--- dom/workers/remoteworkers/RemoteWorkerChild.h | 101 ++++++-- .../remoteworkers/RemoteWorkerController.cpp | 92 ++----- .../remoteworkers/RemoteWorkerController.h | 4 - .../remoteworkers/RemoteWorkerManager.cpp | 18 +- .../remoteworkers/RemoteWorkerManager.h | 1 - ...oteWorkerNonLifeCycleOpControllerChild.cpp | 100 -------- ...emoteWorkerNonLifeCycleOpControllerChild.h | 57 ----- ...teWorkerNonLifeCycleOpControllerParent.cpp | 52 ---- ...moteWorkerNonLifeCycleOpControllerParent.h | 41 --- dom/workers/remoteworkers/RemoteWorkerOp.cpp | 23 -- dom/workers/remoteworkers/RemoteWorkerOp.h | 95 ------- .../RemoteWorkerServiceChild.cpp | 10 +- .../remoteworkers/RemoteWorkerServiceChild.h | 10 +- .../RemoteWorkerServiceParent.cpp | 2 - dom/workers/remoteworkers/moz.build | 7 - dom/workers/sharedworkers/SharedWorkerOp.cpp | 202 --------------- dom/workers/sharedworkers/SharedWorkerOp.h | 47 ---- .../sharedworkers/SharedWorkerOpArgs.ipdlh | 52 ---- dom/workers/sharedworkers/moz.build | 3 - ipc/glue/BackgroundChildImpl.cpp | 1 + 30 files changed, 379 insertions(+), 1010 deletions(-) delete mode 100644 dom/workers/remoteworkers/PRemoteWorkerNonLifeCycleOpController.ipdl delete mode 100644 dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.cpp delete mode 100644 dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.h delete mode 100644 dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.cpp delete mode 100644 dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.h delete mode 100644 dom/workers/remoteworkers/RemoteWorkerOp.cpp delete mode 100644 dom/workers/remoteworkers/RemoteWorkerOp.h delete mode 100644 dom/workers/sharedworkers/SharedWorkerOp.cpp delete mode 100644 dom/workers/sharedworkers/SharedWorkerOp.h delete mode 100644 dom/workers/sharedworkers/SharedWorkerOpArgs.ipdlh diff --git a/dom/serviceworkers/FetchEventOpParent.cpp b/dom/serviceworkers/FetchEventOpParent.cpp index e1d372759427..e5353578aec8 100644 --- a/dom/serviceworkers/FetchEventOpParent.cpp +++ b/dom/serviceworkers/FetchEventOpParent.cpp @@ -17,7 +17,6 @@ #include "mozilla/dom/InternalResponse.h" #include "mozilla/dom/RemoteWorkerControllerParent.h" #include "mozilla/dom/RemoteWorkerParent.h" -#include "mozilla/dom/RemoteWorkerServiceParent.h" #include "mozilla/ipc/BackgroundParent.h" namespace mozilla { diff --git a/dom/serviceworkers/FetchEventOpProxyParent.cpp b/dom/serviceworkers/FetchEventOpProxyParent.cpp index 89c54c42e3b0..ab809972ef34 100644 --- a/dom/serviceworkers/FetchEventOpProxyParent.cpp +++ b/dom/serviceworkers/FetchEventOpProxyParent.cpp @@ -22,9 +22,7 @@ #include "mozilla/dom/InternalResponse.h" #include "mozilla/dom/PRemoteWorkerParent.h" #include "mozilla/dom/PRemoteWorkerControllerParent.h" -#include "mozilla/dom/PRemoteWorkerServiceParent.h" #include "mozilla/dom/FetchEventOpParent.h" -#include "mozilla/ipc/PBackgroundParent.h" #include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/IPCStreamUtils.h" #include "mozilla/RemoteLazyInputStreamStorage.h" diff --git a/dom/serviceworkers/ServiceWorkerOp.cpp b/dom/serviceworkers/ServiceWorkerOp.cpp index 6e8fcb3e4378..2b11742c6c9c 100644 --- a/dom/serviceworkers/ServiceWorkerOp.cpp +++ b/dom/serviceworkers/ServiceWorkerOp.cpp @@ -51,7 +51,6 @@ #include "mozilla/dom/PerformanceStorage.h" #include "mozilla/dom/PushEventBinding.h" #include "mozilla/dom/RemoteWorkerChild.h" -#include "mozilla/dom/RemoteWorkerNonLifeCycleOpControllerChild.h" #include "mozilla/dom/RemoteWorkerService.h" #include "mozilla/dom/Request.h" #include "mozilla/dom/Response.h" @@ -67,11 +66,6 @@ namespace mozilla::dom { -using remoteworker::Canceled; -using remoteworker::Killed; -using remoteworker::Pending; -using remoteworker::Running; - namespace { class ExtendableEventKeepAliveHandler final @@ -286,6 +280,7 @@ class ServiceWorkerOp::ServiceWorkerOpRunnable final WorkerPrivate* aWorkerPrivate) : WorkerDebuggeeRunnable("ServiceWorkerOpRunnable"), mOwner(std::move(aOwner)) { + AssertIsOnMainThread(); MOZ_ASSERT(mOwner); MOZ_ASSERT(aWorkerPrivate); } @@ -311,12 +306,6 @@ class ServiceWorkerOp::ServiceWorkerOpRunnable final return rv; } - // Silent PreDispatch and PostDispatch, since ServiceWorkerOpRunnable can be - // from the main thread or from the worker thread. - bool PreDispatch(WorkerPrivate* WorkerPrivate) override { return true; } - void PostDispatch(WorkerPrivate* WorkerPrivate, - bool aDispatchResult) override {} - nsresult Cancel() override { MOZ_ASSERT(mOwner); @@ -333,7 +322,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(ServiceWorkerOp::ServiceWorkerOpRunnable, WorkerThreadRunnable) bool ServiceWorkerOp::MaybeStart(RemoteWorkerChild* aOwner, - RemoteWorkerState& aState) { + RemoteWorkerChild::State& aState) { MOZ_ASSERT(!mStarted); MOZ_ASSERT(aOwner); MOZ_ASSERT(aOwner->GetActorEventTarget()->IsOnCurrentThread()); @@ -351,13 +340,14 @@ bool ServiceWorkerOp::MaybeStart(RemoteWorkerChild* aOwner, return false; } - if (NS_WARN_IF(aState.is()) || NS_WARN_IF(aState.is())) { + if (NS_WARN_IF(aState.is()) || + NS_WARN_IF(aState.is())) { RejectAll(NS_ERROR_DOM_INVALID_STATE_ERR); mStarted = true; return true; } - MOZ_ASSERT(aState.is() || IsTerminationOp()); + MOZ_ASSERT(aState.is() || IsTerminationOp()); RefPtr self = this; @@ -395,7 +385,6 @@ bool ServiceWorkerOp::MaybeStart(RemoteWorkerChild* aOwner, } void ServiceWorkerOp::StartOnMainThread(RefPtr& aOwner) { - AssertIsOnMainThread(); MaybeReportServiceWorkerShutdownProgress(mArgs); { @@ -423,49 +412,14 @@ void ServiceWorkerOp::StartOnMainThread(RefPtr& aOwner) { } } -void ServiceWorkerOp::Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, - RemoteWorkerState& aState) { - MOZ_ASSERT(!mStarted); - MOZ_ASSERT(aOwner); - - if (NS_WARN_IF(!aOwner->CanSend())) { - RejectAll(NS_ERROR_DOM_ABORT_ERR); - mStarted = true; - return; - } - - // NonLifeCycle related operations would never start at Pending state. - MOZ_ASSERT(!aState.is()); - - if (NS_WARN_IF(aState.is()) || NS_WARN_IF(aState.is())) { - RejectAll(NS_ERROR_DOM_INVALID_STATE_ERR); - mStarted = true; - return; - } - - MOZ_ASSERT(aState.is()); - - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - - MOZ_ASSERT_DEBUG_OR_FUZZING(workerPrivate); - - RefPtr workerRunnable = GetRunnable(workerPrivate); - - if (NS_WARN_IF(!workerRunnable->Dispatch(workerPrivate))) { - RejectAll(NS_ERROR_FAILURE); - } - - mStarted = true; -} - void ServiceWorkerOp::Cancel() { RejectAll(NS_ERROR_DOM_ABORT_ERR); } ServiceWorkerOp::ServiceWorkerOp( ServiceWorkerOpArgs&& aArgs, std::function&& aCallback) : mArgs(std::move(aArgs)) { - // Can be on the Worker Launcher thread for Terminate operations or on the - // Worker thread for other operations + MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread()); + RefPtr promise = mPromiseHolder.Ensure(__func__); promise->Then( @@ -489,6 +443,7 @@ ServiceWorkerOp::~ServiceWorkerOp() { bool ServiceWorkerOp::Started() const { MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread()); + return mStarted; } @@ -499,6 +454,7 @@ bool ServiceWorkerOp::IsTerminationOp() const { RefPtr ServiceWorkerOp::GetRunnable( WorkerPrivate* aWorkerPrivate) { + AssertIsOnMainThread(); MOZ_ASSERT(aWorkerPrivate); return new ServiceWorkerOpRunnable(this, aWorkerPrivate); @@ -560,27 +516,17 @@ class UpdateServiceWorkerStateOp final : public ServiceWorkerOp { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UpdateServiceWorkerStateOp, override); private: - class UpdateStateOpRunnable final : public WorkerControlRunnable { + class UpdateStateOpRunnable final : public MainThreadWorkerControlRunnable { public: NS_DECL_ISUPPORTS_INHERITED UpdateStateOpRunnable(RefPtr aOwner, WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable("UpdateStateOpRunnable"), + : MainThreadWorkerControlRunnable("UpdateStateOpRunnable"), mOwner(std::move(aOwner)) { + AssertIsOnMainThread(); MOZ_ASSERT(mOwner); MOZ_ASSERT(aWorkerPrivate); - aWorkerPrivate->AssertIsOnWorkerThread(); - } - - virtual bool PreDispatch(WorkerPrivate* aWorkerPrivate) override { - aWorkerPrivate->AssertIsOnWorkerThread(); - return true; - } - - virtual void PostDispatch(WorkerPrivate* aWorkerPrivate, - bool aDispatchResult) override { - aWorkerPrivate->AssertIsOnWorkerThread(); } private: @@ -615,8 +561,8 @@ class UpdateServiceWorkerStateOp final : public ServiceWorkerOp { RefPtr GetRunnable( WorkerPrivate* aWorkerPrivate) override { + AssertIsOnMainThread(); MOZ_ASSERT(aWorkerPrivate); - aWorkerPrivate->IsOnWorkerThread(); MOZ_ASSERT(mArgs.type() == ServiceWorkerOpArgs::TServiceWorkerUpdateStateOpArgs); @@ -640,7 +586,7 @@ class UpdateServiceWorkerStateOp final : public ServiceWorkerOp { }; NS_IMPL_ISUPPORTS_INHERITED0(UpdateServiceWorkerStateOp::UpdateStateOpRunnable, - WorkerControlRunnable) + MainThreadWorkerControlRunnable) void ExtendableEventOp::FinishedWithResult(ExtendableEventResult aResult) { MOZ_ASSERT(IsCurrentThreadRunningWorker()); @@ -1927,8 +1873,8 @@ class ExtensionAPIEventOp final : public ServiceWorkerOp { /* static */ already_AddRefed ServiceWorkerOp::Create( ServiceWorkerOpArgs&& aArgs, std::function&& aCallback) { - // Can be on the Worker Launcher thread for Terminate operations or on the - // Worker thread for other operations. + MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread()); + RefPtr op; switch (aArgs.type()) { diff --git a/dom/serviceworkers/ServiceWorkerOp.h b/dom/serviceworkers/ServiceWorkerOp.h index 2312c84ac48c..3d872a00e574 100644 --- a/dom/serviceworkers/ServiceWorkerOp.h +++ b/dom/serviceworkers/ServiceWorkerOp.h @@ -20,17 +20,14 @@ #include "mozilla/TimeStamp.h" #include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/dom/RemoteWorkerChild.h" -#include "mozilla/dom/RemoteWorkerOp.h" #include "mozilla/dom/ServiceWorkerOpArgs.h" #include "mozilla/dom/WorkerRunnable.h" namespace mozilla::dom { -using remoteworker::RemoteWorkerState; - class FetchEventOpProxyChild; -class ServiceWorkerOp : public RemoteWorkerOp { +class ServiceWorkerOp : public RemoteWorkerChild::Op { public: // `aCallback` will be called when the operation completes or is canceled. static already_AddRefed Create( @@ -50,13 +47,11 @@ class ServiceWorkerOp : public RemoteWorkerOp { ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default; // Returns `true` if the operation has started and `false` otherwise. - bool MaybeStart(RemoteWorkerChild* aOwner, RemoteWorkerState& aState) final; + bool MaybeStart(RemoteWorkerChild* aOwner, + RemoteWorkerChild::State& aState) final; void StartOnMainThread(RefPtr& aOwner) final; - void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, - RemoteWorkerState& aState) final; - void Cancel() final; protected: diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 7d7965d9e230..b05d13a96cbb 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -50,7 +50,6 @@ #include "mozilla/dom/PromiseDebugging.h" #include "mozilla/dom/ReferrerInfo.h" #include "mozilla/dom/RemoteWorkerChild.h" -#include "mozilla/dom/RemoteWorkerNonLifeCycleOpControllerChild.h" #include "mozilla/dom/RemoteWorkerService.h" #include "mozilla/dom/RootedDictionary.h" #include "mozilla/dom/SimpleGlobalObject.h" @@ -2437,9 +2436,7 @@ WorkerPrivate::WorkerPrivate( nsString&& aId, const nsID& aAgentClusterId, const nsILoadInfo::CrossOriginOpenerPolicy aAgentClusterOpenerPolicy, CancellationCallback&& aCancellationCallback, - TerminationCallback&& aTerminationCallback, - mozilla::ipc::Endpoint&& - aChildEp) + TerminationCallback&& aTerminationCallback) : mMutex("WorkerPrivate Mutex"), mCondVar(mMutex, "WorkerPrivate CondVar"), mParent(aParent), @@ -2458,7 +2455,6 @@ WorkerPrivate::WorkerPrivate( this, WorkerEventTarget::Behavior::ControlOnly)), mWorkerHybridEventTarget( new WorkerEventTarget(this, WorkerEventTarget::Behavior::Hybrid)), - mChildEp(std::move(aChildEp)), mParentStatus(Pending), mStatus(Pending), mCreationTimeStamp(TimeStamp::Now()), @@ -2676,9 +2672,7 @@ already_AddRefed WorkerPrivate::Constructor( const nsACString& aServiceWorkerScope, WorkerLoadInfo* aLoadInfo, ErrorResult& aRv, nsString aId, CancellationCallback&& aCancellationCallback, - TerminationCallback&& aTerminationCallback, - mozilla::ipc::Endpoint&& - aChildEp) { + TerminationCallback&& aTerminationCallback) { WorkerPrivate* parent = NS_IsMainThread() ? nullptr : GetCurrentThreadWorkerPrivate(); @@ -2743,7 +2737,7 @@ already_AddRefed WorkerPrivate::Constructor( parent, aScriptURL, aIsChromeWorker, aWorkerKind, aRequestCredentials, aWorkerType, aWorkerName, aServiceWorkerScope, *aLoadInfo, std::move(aId), idAndCoop.mId, idAndCoop.mCoop, std::move(aCancellationCallback), - std::move(aTerminationCallback), std::move(aChildEp)); + std::move(aTerminationCallback)); // Gecko contexts always have an explicitly-set default locale (set by // XPJSRuntime::Initialize for the main thread, set by @@ -3287,19 +3281,6 @@ void WorkerPrivate::DoRunLoop(JSContext* aCx) { MOZ_ASSERT(mStatus == Pending); mStatus = Running; - // Create IPC between the content process worker thread and the parent - // process background thread for non-life cycle related operations of - // SharedWorker/ServiceWorker - if (mChildEp.IsValid()) { - mRemoteWorkerNonLifeCycleOpController = - RemoteWorkerNonLifeCycleOpControllerChild::Create(); - // RemoteWorkerNonLifeCycleOpControllerChild::Create() can fail when - // Worker enters "Canceling." But Worker just gets into "Running," - // probably can replace the if statement with an assertion. - MOZ_ASSERT_DEBUG_OR_FUZZING(mRemoteWorkerNonLifeCycleOpController); - mChildEp.Bind(mRemoteWorkerNonLifeCycleOpController); - } - // Now, start to run the event loop, mPreStartRunnables can be cleared, // since when get here, Worker initialization has done successfully. mPreStartRunnables.Clear(); @@ -5225,15 +5206,6 @@ bool WorkerPrivate::NotifyInternal(WorkerStatus aStatus) { NotifyWorkerRefs(aStatus); } - if (aStatus == Canceling && mRemoteWorkerNonLifeCycleOpController) { - mRemoteWorkerNonLifeCycleOpController->TransistionStateToCanceled(); - } - - if (aStatus == Killing && mRemoteWorkerNonLifeCycleOpController) { - mRemoteWorkerNonLifeCycleOpController->TransistionStateToKilled(); - mRemoteWorkerNonLifeCycleOpController = nullptr; - } - // If the worker script never ran, or failed to compile, we don't need to do // anything else. WorkerGlobalScope* global = GlobalScope(); diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index ebd84d906023..f40b0a082fff 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -28,8 +28,6 @@ #include "mozilla/UseCounter.h" #include "mozilla/dom/ClientSource.h" #include "mozilla/dom/FlippedOnce.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerChild.h" -#include "mozilla/dom/RemoteWorkerTypes.h" #include "mozilla/dom/Timeout.h" #include "mozilla/dom/quota/CheckedUnsafePtr.h" #include "mozilla/dom/Worker.h" @@ -40,13 +38,11 @@ #include "mozilla/dom/workerinternals/JSSettings.h" #include "mozilla/dom/workerinternals/Queue.h" #include "mozilla/dom/JSExecutionManager.h" -#include "mozilla/ipc/Endpoint.h" #include "mozilla/net/NeckoChannelParams.h" #include "mozilla/StaticPrefs_extensions.h" #include "nsContentUtils.h" #include "nsIChannel.h" #include "nsIContentSecurityPolicy.h" -#include "nsID.h" #include "nsIEventTarget.h" #include "nsILoadInfo.h" #include "nsRFPService.h" @@ -64,7 +60,6 @@ class ThrottledEventQueue; namespace dom { class RemoteWorkerChild; -class RemoteWorkerNonLifeCycleOpControllerChild; // If you change this, the corresponding list in nsIWorkerDebugger.idl needs // to be updated too. And histograms enum for worker use counters uses the same @@ -236,10 +231,7 @@ class WorkerPrivate final const nsACString& aServiceWorkerScope, WorkerLoadInfo* aLoadInfo, ErrorResult& aRv, nsString aId = u""_ns, CancellationCallback&& aCancellationCallback = {}, - TerminationCallback&& aTerminationCallback = {}, - mozilla::ipc::Endpoint< - PRemoteWorkerNonLifeCycleOpControllerChild>&& aChildEp = - mozilla::ipc::Endpoint()); + TerminationCallback&& aTerminationCallback = {}); enum LoadGroupBehavior { InheritLoadGroup, OverrideLoadGroup }; @@ -1204,9 +1196,7 @@ class WorkerPrivate final nsString&& aId, const nsID& aAgentClusterId, const nsILoadInfo::CrossOriginOpenerPolicy aAgentClusterOpenerPolicy, CancellationCallback&& aCancellationCallback, - TerminationCallback&& aTerminationCallback, - mozilla::ipc::Endpoint&& - aChildEp); + TerminationCallback&& aTerminationCallback); ~WorkerPrivate(); @@ -1453,13 +1443,6 @@ class WorkerPrivate final // ServiceWorker RemoteWorkers. RefPtr mRemoteWorkerController; - // Only touched on the worker thread. Used for both SharedWorker and - // ServiceWorker RemoteWorkers. - RefPtr - mRemoteWorkerNonLifeCycleOpController; - - mozilla::ipc::Endpoint mChildEp; - JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init TimeStamp mKillTime; WorkerStatus mParentStatus MOZ_GUARDED_BY(mMutex); diff --git a/dom/workers/remoteworkers/PRemoteWorker.ipdl b/dom/workers/remoteworkers/PRemoteWorker.ipdl index 51983a7feac2..6777b2ffbcf6 100644 --- a/dom/workers/remoteworkers/PRemoteWorker.ipdl +++ b/dom/workers/remoteworkers/PRemoteWorker.ipdl @@ -5,13 +5,54 @@ include protocol PFetchEventOpProxy; include protocol PRemoteWorkerService; +include DOMTypes; include ServiceWorkerOpArgs; -include SharedWorkerOpArgs; include RemoteWorkerTypes; namespace mozilla { namespace dom { +struct RemoteWorkerSuspendOp +{}; + +struct RemoteWorkerResumeOp +{}; + +struct RemoteWorkerFreezeOp +{}; + +struct RemoteWorkerThawOp +{}; + +struct RemoteWorkerTerminateOp +{}; + +struct RemoteWorkerPortIdentifierOp +{ + MessagePortIdentifier portIdentifier; +}; + +struct RemoteWorkerAddWindowIDOp +{ + uint64_t windowID; +}; + +struct RemoteWorkerRemoveWindowIDOp +{ + uint64_t windowID; +}; + +union RemoteWorkerOp { + RemoteWorkerSuspendOp; + RemoteWorkerResumeOp; + RemoteWorkerFreezeOp; + RemoteWorkerThawOp; + RemoteWorkerTerminateOp; + RemoteWorkerPortIdentifierOp; + RemoteWorkerAddWindowIDOp; + RemoteWorkerRemoveWindowIDOp; +}; + // This protocol is used to make a remote worker controllable from the parent // process. The parent process will receive operations from the // PRemoteWorkerController protocol. @@ -39,7 +80,7 @@ child: async __delete__(); - async ExecOp(SharedWorkerOpArgs aArgs); + async ExecOp(RemoteWorkerOp op); async ExecServiceWorkerOp(ServiceWorkerOpArgs aArgs) returns (ServiceWorkerOpResult aResult); diff --git a/dom/workers/remoteworkers/PRemoteWorkerNonLifeCycleOpController.ipdl b/dom/workers/remoteworkers/PRemoteWorkerNonLifeCycleOpController.ipdl deleted file mode 100644 index 1fce92c3f7a1..000000000000 --- a/dom/workers/remoteworkers/PRemoteWorkerNonLifeCycleOpController.ipdl +++ /dev/null @@ -1,31 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include RemoteWorkerTypes; -include ServiceWorkerOpArgs; -include SharedWorkerOpArgs; - -namespace mozilla { -namespace dom{ - -[ChildProc=any] -protocol PRemoteWorkerNonLifeCycleOpController -{ - -parent: - async Terminated(); - - async Error(ErrorValue aValue); - -child: - async ExecOp(SharedWorkerOpArgs aOpArgs); - - async ExecServiceWorkerOp(ServiceWorkerOpArgs aOpArgs) - returns (ServiceWorkerOpResult aResult) ; - - async Shutdown(); -}; - -} // namespace dom -} // namespace mozilla diff --git a/dom/workers/remoteworkers/PRemoteWorkerService.ipdl b/dom/workers/remoteworkers/PRemoteWorkerService.ipdl index 30cfb6aa1de8..905d69081a74 100644 --- a/dom/workers/remoteworkers/PRemoteWorkerService.ipdl +++ b/dom/workers/remoteworkers/PRemoteWorkerService.ipdl @@ -3,7 +3,6 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ include protocol PRemoteWorker; -include protocol PRemoteWorkerNonLifeCycleOpController; include ProtocolTypes; include RemoteWorkerTypes; @@ -20,8 +19,7 @@ protocol PRemoteWorkerService manages PRemoteWorker; child: - async PRemoteWorker(RemoteWorkerData data, - Endpoint childEp); + async PRemoteWorker(RemoteWorkerData data); }; } // namespace dom diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerChild.cpp index 861adbdd61c4..9a4ca6028703 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp @@ -40,7 +40,6 @@ #include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h" #include "mozilla/dom/ServiceWorkerShutdownState.h" #include "mozilla/dom/ServiceWorkerUtils.h" -#include "mozilla/dom/SharedWorkerOp.h" #include "mozilla/dom/workerinternals/ScriptLoader.h" #include "mozilla/dom/WorkerError.h" #include "mozilla/dom/WorkerPrivate.h" @@ -67,11 +66,6 @@ namespace dom { using workerinternals::ChannelFromScriptURLMainThread; -using remoteworker::Canceled; -using remoteworker::Killed; -using remoteworker::Pending; -using remoteworker::Running; - namespace { class SharedWorkerInterfaceRequestor final : public nsIInterfaceRequestor { @@ -111,6 +105,30 @@ NS_IMPL_ADDREF(SharedWorkerInterfaceRequestor) NS_IMPL_RELEASE(SharedWorkerInterfaceRequestor) NS_IMPL_QUERY_INTERFACE(SharedWorkerInterfaceRequestor, nsIInterfaceRequestor) +// Normal runnable because AddPortIdentifier() is going to exec JS code. +class MessagePortIdentifierRunnable final : public WorkerThreadRunnable { + public: + MessagePortIdentifierRunnable(WorkerPrivate* aWorkerPrivate, + RemoteWorkerChild* aActor, + const MessagePortIdentifier& aPortIdentifier) + : WorkerThreadRunnable("MessagePortIdentifierRunnable"), + mActor(aActor), + mPortIdentifier(aPortIdentifier) {} + + private: + bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { + if (aWorkerPrivate->GlobalScope()->IsDying()) { + mPortIdentifier.ForceClose(); + return true; + } + mActor->AddPortIdentifier(aCx, aWorkerPrivate, mPortIdentifier); + return true; + } + + RefPtr mActor; + UniqueMessagePortId mPortIdentifier; +}; + // This is used to propagate the CSP violation when loading the SharedWorker // main-script and nothing else. class RemoteWorkerCSPEventListener final : public nsICSPEventListener { @@ -118,7 +136,7 @@ class RemoteWorkerCSPEventListener final : public nsICSPEventListener { NS_DECL_ISUPPORTS explicit RemoteWorkerCSPEventListener(RemoteWorkerChild* aActor) - : mActor(aActor) {}; + : mActor(aActor){}; NS_IMETHOD OnCSPViolationEvent(const nsAString& aJSON) override { mActor->CSPViolationPropagationOnMainThread(aJSON); @@ -136,7 +154,7 @@ NS_IMPL_ISUPPORTS(RemoteWorkerCSPEventListener, nsICSPEventListener) } // anonymous namespace RemoteWorkerChild::RemoteWorkerChild(const RemoteWorkerData& aData) - : mState(VariantType(), "RemoteWorkerState"), + : mState(VariantType(), "RemoteWorkerChild::mState"), mServiceKeepAlive(RemoteWorkerService::MaybeGetKeepAlive()), mIsServiceWorker(aData.serviceWorkerData().type() == OptionalServiceWorkerData::TServiceWorkerData) { @@ -187,10 +205,7 @@ void RemoteWorkerChild::ActorDestroy(ActorDestroyReason) { } } -void RemoteWorkerChild::ExecWorker( - const RemoteWorkerData& aData, - mozilla::ipc::Endpoint&& - aChildEp) { +void RemoteWorkerChild::ExecWorker(const RemoteWorkerData& aData) { #ifdef DEBUG MOZ_ASSERT(GetActorEventTarget()->IsOnCurrentThread()); auto launcherData = mLauncherData.Access(); @@ -200,10 +215,8 @@ void RemoteWorkerChild::ExecWorker( RefPtr self = this; nsCOMPtr r = NS_NewRunnableFunction( - __func__, [self = std::move(self), data = aData, - childEp = std::move(aChildEp)]() mutable { - nsresult rv = - self->ExecWorkerOnMainThread(std::move(data), std::move(childEp)); + __func__, [self = std::move(self), data = aData]() mutable { + nsresult rv = self->ExecWorkerOnMainThread(std::move(data)); // Creation failure will already have been reported via the method // above internally using ScopeExit. @@ -213,10 +226,7 @@ void RemoteWorkerChild::ExecWorker( MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r.forget())); } -nsresult RemoteWorkerChild::ExecWorkerOnMainThread( - RemoteWorkerData&& aData, - mozilla::ipc::Endpoint&& - aChildEp) { +nsresult RemoteWorkerChild::ExecWorkerOnMainThread(RemoteWorkerData&& aData) { MOZ_ASSERT(NS_IsMainThread()); // Ensure that the IndexedDatabaseManager is initialized so that if any @@ -385,8 +395,7 @@ nsresult RemoteWorkerChild::ExecWorkerOnMainThread( // begin to transition when the worker thread would reach the Canceling // state. This lambda ensures that we not only wait for the Killing state // to be reached but that the global shutdown has already occurred. - [self]() { self->TransitionStateFromCanceledToKilled(); }, - std::move(aChildEp)); + [self]() { self->TransitionStateFromCanceledToKilled(); }); if (NS_WARN_IF(error.Failed())) { MOZ_ASSERT(!workerPrivate); @@ -668,6 +677,22 @@ void RemoteWorkerChild::FlushReportsOnMainThread( /** * Worker state transition methods */ +RemoteWorkerChild::WorkerPrivateAccessibleState:: + ~WorkerPrivateAccessibleState() { + // We should now only be performing state transitions on the main thread, so + // we should assert we're only releasing on the main thread. + MOZ_ASSERT(!mWorkerPrivate || NS_IsMainThread()); + // mWorkerPrivate can be safely released on the main thread. + if (!mWorkerPrivate || NS_IsMainThread()) { + return; + } + + // But as a backstop, do proxy the release to the main thread. + NS_ReleaseOnMainThread( + "RemoteWorkerChild::WorkerPrivateAccessibleState::mWorkerPrivate", + mWorkerPrivate.forget()); +} + void RemoteWorkerChild:: OnWorkerCancellationTransitionStateFromPendingOrRunningToCanceled() { auto lock = mState.Lock(); @@ -677,21 +702,20 @@ void RemoteWorkerChild:: if (lock->is()) { TransitionStateFromPendingToCanceled(lock.ref()); } else if (lock->is()) { - *lock = VariantType(); + *lock = VariantType(); } else { MOZ_ASSERT(false, "State should have been Pending or Running"); } } -void RemoteWorkerChild::TransitionStateFromPendingToCanceled( - RemoteWorkerState& aState) { +void RemoteWorkerChild::TransitionStateFromPendingToCanceled(State& aState) { AssertIsOnMainThread(); MOZ_ASSERT(aState.is()); LOG(("TransitionStateFromPendingToCanceled[this=%p]", this)); CancelAllPendingOps(aState); - aState = VariantType(); + aState = VariantType(); } void RemoteWorkerChild::TransitionStateFromCanceledToKilled() { @@ -702,7 +726,7 @@ void RemoteWorkerChild::TransitionStateFromCanceledToKilled() { auto lock = mState.Lock(); MOZ_ASSERT(lock->is()); - *lock = VariantType(); + *lock = VariantType(); RefPtr self = this; nsCOMPtr r = NS_NewRunnableFunction(__func__, [self]() { @@ -730,7 +754,7 @@ void RemoteWorkerChild::TransitionStateToRunning() { LOG(("TransitionStateToRunning[this=%p]", this)); - nsTArray> pendingOps; + nsTArray> pendingOps; { auto lock = mState.Lock(); @@ -751,7 +775,7 @@ void RemoteWorkerChild::TransitionStateToRunning() { // Move the worker private into place to avoid gratuitous ref churn; prior // comments here suggest the Variant can't accept a move. - *lock = VariantType(); + *lock = VariantType(); lock->as().mWorkerPrivate = std::move(workerPrivate); } @@ -805,7 +829,153 @@ void RemoteWorkerChild::ExceptionalErrorTransitionDuringExecWorker() { } } -void RemoteWorkerChild::CancelAllPendingOps(RemoteWorkerState& aState) { +/** + * Operation execution classes/methods + */ +class RemoteWorkerChild::SharedWorkerOp : public RemoteWorkerChild::Op { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerOp, override) + + explicit SharedWorkerOp(RemoteWorkerOp&& aOp) : mOp(std::move(aOp)) {} + + bool MaybeStart(RemoteWorkerChild* aOwner, + RemoteWorkerChild::State& aState) override { + MOZ_ASSERT(!mStarted); + MOZ_ASSERT(aOwner); + // Thread: We are on the Worker Launcher thread. + + // Return false, indicating we should queue this op if our current state is + // pending and this isn't a termination op (which should skip the line). + if (aState.is() && !IsTerminationOp()) { + return false; + } + + // If the worker is already shutting down (which should be unexpected + // because we should be told new operations after a termination op), just + // return true to indicate the op should be discarded. + if (aState.is() || aState.is()) { +#ifdef DEBUG + mStarted = true; +#endif + if (mOp.type() == RemoteWorkerOp::TRemoteWorkerPortIdentifierOp) { + MessagePort::ForceClose( + mOp.get_RemoteWorkerPortIdentifierOp().portIdentifier()); + } + return true; + } + + MOZ_ASSERT(aState.is() || IsTerminationOp()); + + RefPtr self = this; + RefPtr owner = aOwner; + + nsCOMPtr r = NS_NewRunnableFunction( + __func__, [self = std::move(self), owner = std::move(owner)]() mutable { + { + auto lock = owner->mState.Lock(); + + if (NS_WARN_IF(lock->is() || lock->is())) { + self->Cancel(); + // Worker has already canceled, force close the MessagePort. + if (self->mOp.type() == + RemoteWorkerOp::TRemoteWorkerPortIdentifierOp) { + MessagePort::ForceClose( + self->mOp.get_RemoteWorkerPortIdentifierOp() + .portIdentifier()); + } + return; + } + } + + self->StartOnMainThread(owner); + }); + + MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r.forget())); + +#ifdef DEBUG + mStarted = true; +#endif + + return true; + } + + void StartOnMainThread(RefPtr& aOwner) final { + using Running = RemoteWorkerChild::Running; + + AssertIsOnMainThread(); + + if (IsTerminationOp()) { + aOwner->CloseWorkerOnMainThread(); + return; + } + + auto lock = aOwner->mState.Lock(); + MOZ_ASSERT(lock->is()); + if (!lock->is()) { + aOwner->ErrorPropagationDispatch(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + + RefPtr workerPrivate = lock->as().mWorkerPrivate; + + MOZ_ASSERT(workerPrivate); + + if (mOp.type() == RemoteWorkerOp::TRemoteWorkerSuspendOp) { + workerPrivate->ParentWindowPaused(); + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerResumeOp) { + workerPrivate->ParentWindowResumed(); + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerFreezeOp) { + workerPrivate->Freeze(nullptr); + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerThawOp) { + workerPrivate->Thaw(nullptr); + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerPortIdentifierOp) { + RefPtr r = + new MessagePortIdentifierRunnable( + workerPrivate, aOwner, + mOp.get_RemoteWorkerPortIdentifierOp().portIdentifier()); + if (NS_WARN_IF(!r->Dispatch(workerPrivate))) { + aOwner->ErrorPropagationDispatch(NS_ERROR_FAILURE); + } + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerAddWindowIDOp) { + aOwner->mWindowIDs.AppendElement( + mOp.get_RemoteWorkerAddWindowIDOp().windowID()); + } else if (mOp.type() == RemoteWorkerOp::TRemoteWorkerRemoveWindowIDOp) { + aOwner->mWindowIDs.RemoveElement( + mOp.get_RemoteWorkerRemoveWindowIDOp().windowID()); + } else { + MOZ_CRASH("Unknown RemoteWorkerOp type!"); + } + } + + void Cancel() override { +#ifdef DEBUG + mStarted = true; +#endif + } + + private: + ~SharedWorkerOp() { MOZ_ASSERT(mStarted); } + + bool IsTerminationOp() const { + return mOp.type() == RemoteWorkerOp::TRemoteWorkerTerminateOp; + } + + RemoteWorkerOp mOp; + +#ifdef DEBUG + bool mStarted = false; +#endif +}; + +void RemoteWorkerChild::AddPortIdentifier( + JSContext* aCx, WorkerPrivate* aWorkerPrivate, + UniqueMessagePortId& aPortIdentifier) { + if (NS_WARN_IF(!aWorkerPrivate->ConnectMessagePort(aCx, aPortIdentifier))) { + ErrorPropagationDispatch(NS_ERROR_FAILURE); + } +} + +void RemoteWorkerChild::CancelAllPendingOps(State& aState) { MOZ_ASSERT(aState.is()); auto pendingOps = std::move(aState.as().mPendingOps); @@ -815,7 +985,7 @@ void RemoteWorkerChild::CancelAllPendingOps(RemoteWorkerState& aState) { } } -void RemoteWorkerChild::MaybeStartOp(RefPtr&& aOp) { +void RemoteWorkerChild::MaybeStartOp(RefPtr&& aOp) { MOZ_ASSERT(aOp); auto lock = mState.Lock(); @@ -826,10 +996,10 @@ void RemoteWorkerChild::MaybeStartOp(RefPtr&& aOp) { } } -IPCResult RemoteWorkerChild::RecvExecOp(SharedWorkerOpArgs&& aOpArgs) { +IPCResult RemoteWorkerChild::RecvExecOp(RemoteWorkerOp&& aOp) { MOZ_ASSERT(!mIsServiceWorker); - MaybeStartOp(new SharedWorkerOp(std::move(aOpArgs))); + MaybeStartOp(new SharedWorkerOp(std::move(aOp))); return IPC_OK(); } diff --git a/dom/workers/remoteworkers/RemoteWorkerChild.h b/dom/workers/remoteworkers/RemoteWorkerChild.h index ed611eb87dcc..cdb2fb32d700 100644 --- a/dom/workers/remoteworkers/RemoteWorkerChild.h +++ b/dom/workers/remoteworkers/RemoteWorkerChild.h @@ -16,24 +16,18 @@ #include "mozilla/RefPtr.h" #include "mozilla/ThreadBound.h" #include "mozilla/dom/PRemoteWorkerChild.h" -#include "mozilla/dom/RemoteWorkerOp.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerChild.h" #include "mozilla/dom/ServiceWorkerOpArgs.h" -#include "mozilla/dom/SharedWorkerOpArgs.h" class nsISerialEventTarget; class nsIConsoleReportCollector; namespace mozilla::dom { -using remoteworker::RemoteWorkerState; - class ErrorValue; class FetchEventOpProxyChild; class RemoteWorkerData; class RemoteWorkerServiceKeepAlive; class ServiceWorkerOp; -class SharedWorkerOp; class UniqueMessagePortId; class WeakWorkerRef; class WorkerErrorReport; @@ -50,7 +44,6 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { friend class FetchEventOpProxyChild; friend class PRemoteWorkerChild; friend class ServiceWorkerOp; - friend class SharedWorkerOp; ~RemoteWorkerChild(); @@ -62,10 +55,7 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { explicit RemoteWorkerChild(const RemoteWorkerData& aData); - void ExecWorker( - const RemoteWorkerData& aData, - mozilla::ipc::Endpoint&& - aChildEp); + void ExecWorker(const RemoteWorkerData& aData); void ErrorPropagationOnMainThread(const WorkerErrorReport* aReport, bool aIsErrorEvent); @@ -78,6 +68,9 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter); + void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate, + UniqueMessagePortId& aPortIdentifier); + RefPtr GetTerminationPromise(); RefPtr MaybeSendSetServiceWorkerSkipWaitingFlag(); @@ -87,17 +80,86 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { private: class InitializeWorkerRunnable; + class Op; + class SharedWorkerOp; + + struct WorkerPrivateAccessibleState { + ~WorkerPrivateAccessibleState(); + RefPtr mWorkerPrivate; + }; + + // Initial state, mWorkerPrivate is initially null but will be initialized on + // the main thread by ExecWorkerOnMainThread when the WorkerPrivate is + // created. The state will transition to Running or Canceled, also from the + // main thread. + struct Pending : WorkerPrivateAccessibleState { + nsTArray> mPendingOps; + }; + + // Running, with the state transition happening on the main thread as a result + // of the worker successfully processing our initialization runnable, + // indicating that top-level script execution successfully completed. Because + // all of our state transitions happen on the main thread and are posed in + // terms of the main thread's perspective of the worker's state, it's very + // possible for us to skip directly from Pending to Canceled because we decide + // to cancel/terminate the worker prior to it finishing script loading or + // reporting back to us. + struct Running : WorkerPrivateAccessibleState {}; + + // Cancel() has been called on the WorkerPrivate on the main thread by a + // TerminationOp, top-level script evaluation has failed and canceled the + // worker, or in the case of a SharedWorker, close() has been called on + // the global scope by content code and the worker has advanced to the + // Canceling state. (Dedicated Workers can also self close, but they will + // never be RemoteWorkers. Although a SharedWorker can own DedicatedWorkers.) + // Browser shutdown will result in a TerminationOp thanks to use of a shutdown + // blocker in the parent, so the RuntimeService shouldn't get involved, but we + // would also handle that case acceptably too. + // + // Because worker self-closing is still handled by dispatching a runnable to + // the main thread to effectively call WorkerPrivate::Cancel(), there isn't + // a race between a worker deciding to self-close and our termination ops. + // + // In this state, we have dropped the reference to the WorkerPrivate and will + // no longer be dispatching runnables to the worker. We wait in this state + // until the termination lambda is invoked letting us know that the worker has + // entirely shutdown and we can advanced to the Killed state. + struct Canceled {}; + + // The worker termination lambda has been invoked and we know the Worker is + // entirely shutdown. (Inherently it is possible for us to advance to this + // state while the nsThread for the worker is still in the process of + // shutting down, but no more worker code will run on it.) + // + // This name is chosen to match the Worker's own state model. + struct Killed {}; + + using State = Variant; + // The state of the WorkerPrivate as perceived by the owner on the main // thread. All state transitions now happen on the main thread, but the // Worker Launcher thread will consult the state and will directly append ops // to the Pending queue - DataMutex mState; + DataMutex mState; const RefPtr mServiceKeepAlive; + class Op { + public: + NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING + + virtual ~Op() = default; + + virtual bool MaybeStart(RemoteWorkerChild* aOwner, State& aState) = 0; + + virtual void StartOnMainThread(RefPtr& aOwner) = 0; + + virtual void Cancel() = 0; + }; + void ActorDestroy(ActorDestroyReason) override; - mozilla::ipc::IPCResult RecvExecOp(SharedWorkerOpArgs&& aOpArgs); + mozilla::ipc::IPCResult RecvExecOp(RemoteWorkerOp&& aOp); mozilla::ipc::IPCResult RecvExecServiceWorkerOp( ServiceWorkerOpArgs&& aArgs, ExecServiceWorkerOpResolver&& aResolve); @@ -109,10 +171,7 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { PFetchEventOpProxyChild* aActor, const ParentToChildServiceWorkerFetchEventOpArgs& aArgs) override; - nsresult ExecWorkerOnMainThread( - RemoteWorkerData&& aData, - mozilla::ipc::Endpoint&& - aChildEp); + nsresult ExecWorkerOnMainThread(RemoteWorkerData&& aData); void ExceptionalErrorTransitionDuringExecWorker(); @@ -147,18 +206,18 @@ class RemoteWorkerChild final : public PRemoteWorkerChild { // the worker hasn't started running, or in exceptional cases where we bail // out of the ExecWorker method early. The caller must be holding the lock // (in order to pass in the state). - void TransitionStateFromPendingToCanceled(RemoteWorkerState& aState); + void TransitionStateFromPendingToCanceled(State& aState); void TransitionStateFromCanceledToKilled(); void TransitionStateToRunning(); void TransitionStateToTerminated(); - void TransitionStateToTerminated(RemoteWorkerState& aState); + void TransitionStateToTerminated(State& aState); - void CancelAllPendingOps(RemoteWorkerState& aState); + void CancelAllPendingOps(State& aState); - void MaybeStartOp(RefPtr&& aOp); + void MaybeStartOp(RefPtr&& aOp); const bool mIsServiceWorker; diff --git a/dom/workers/remoteworkers/RemoteWorkerController.cpp b/dom/workers/remoteworkers/RemoteWorkerController.cpp index faf4d35cdb3f..b0d56aa33dfe 100644 --- a/dom/workers/remoteworkers/RemoteWorkerController.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerController.cpp @@ -23,7 +23,6 @@ #include "mozilla/ipc/BackgroundParent.h" #include "RemoteWorkerControllerParent.h" #include "RemoteWorkerManager.h" -#include "RemoteWorkerNonLifeCycleOpControllerParent.h" #include "RemoteWorkerParent.h" namespace mozilla { @@ -97,7 +96,6 @@ void RemoteWorkerController::CreationFailed() { if (mState == eTerminated) { MOZ_ASSERT(!mActor); - MOZ_ASSERT(!mNonLifeCycleOpController); MOZ_ASSERT(mPendingOps.IsEmpty()); // Nothing to do. return; @@ -114,14 +112,12 @@ void RemoteWorkerController::CreationSucceeded() { if (mState == eTerminated) { MOZ_ASSERT(!mActor); - MOZ_ASSERT(!mNonLifeCycleOpController); MOZ_ASSERT(mPendingOps.IsEmpty()); // Nothing to do. return; } MOZ_ASSERT(mActor); - MOZ_ASSERT(mNonLifeCycleOpController); mState = eReady; mObserver->CreationSucceeded(); @@ -183,11 +179,6 @@ void RemoteWorkerController::Shutdown() { CancelAllPendingOps(); - if (mNonLifeCycleOpController) { - mNonLifeCycleOpController->Shutdown(); - mNonLifeCycleOpController = nullptr; - } - if (!mActor) { return; } @@ -201,7 +192,7 @@ void RemoteWorkerController::Shutdown() { if (mIsServiceWorker) { mActor->MaybeSendDelete(); } else { - Unused << mActor->SendExecOp(SharedWorkerTerminateOpArgs()); + Unused << mActor->SendExecOp(RemoteWorkerTerminateOp()); } mActor = nullptr; @@ -381,39 +372,28 @@ bool RemoteWorkerController::PendingSharedWorkerOp::MaybeStart( aOwner->Shutdown(); break; case eSuspend: - Unused << aOwner->mActor->SendExecOp(SharedWorkerSuspendOpArgs()); + Unused << aOwner->mActor->SendExecOp(RemoteWorkerSuspendOp()); break; case eResume: - Unused << aOwner->mActor->SendExecOp(SharedWorkerResumeOpArgs()); + Unused << aOwner->mActor->SendExecOp(RemoteWorkerResumeOp()); break; case eFreeze: - Unused << aOwner->mActor->SendExecOp(SharedWorkerFreezeOpArgs()); + Unused << aOwner->mActor->SendExecOp(RemoteWorkerFreezeOp()); break; case eThaw: - Unused << aOwner->mActor->SendExecOp(SharedWorkerThawOpArgs()); + Unused << aOwner->mActor->SendExecOp(RemoteWorkerThawOp()); break; case ePortIdentifier: - // mNonLifeCycleOpController can be nullptr if the Worker is in "Killing." - // RemoteWorkerNonLifeCycleOpControllerChild switches to the Killed status - // earlier than RemoteWorkerChild since it switches the status on the - // worker thread, not the main thread. - if (!aOwner->mNonLifeCycleOpController) { - Cancel(); - return true; - } - if (!aOwner->mNonLifeCycleOpController->CanSend()) { - return false; - } - Unused << aOwner->mNonLifeCycleOpController->SendExecOp( - SharedWorkerPortIdentifierOpArgs(mPortIdentifier)); + Unused << aOwner->mActor->SendExecOp( + RemoteWorkerPortIdentifierOp(mPortIdentifier)); break; case eAddWindowID: Unused << aOwner->mActor->SendExecOp( - SharedWorkerAddWindowIDOpArgs(mWindowID)); + RemoteWorkerAddWindowIDOp(mWindowID)); break; case eRemoveWindowID: Unused << aOwner->mActor->SendExecOp( - SharedWorkerRemoveWindowIDOpArgs(mWindowID)); + RemoteWorkerRemoveWindowIDOp(mWindowID)); break; default: MOZ_CRASH("Unknown op."); @@ -491,51 +471,21 @@ bool RemoteWorkerController::PendingServiceWorkerOp::MaybeStart( return false; } - switch (mArgs.type()) { - case ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs: - case ServiceWorkerOpArgs::TParentToChildServiceWorkerFetchEventOpArgs: { - MaybeReportServiceWorkerShutdownProgress(mArgs); + MaybeReportServiceWorkerShutdownProgress(mArgs); - aOwner->mActor->SendExecServiceWorkerOp(mArgs)->Then( - GetCurrentSerialEventTarget(), __func__, - [promise = std::move(mPromise)]( - PRemoteWorkerParent::ExecServiceWorkerOpPromise:: - ResolveOrRejectValue&& aResult) { - if (NS_WARN_IF(aResult.IsReject())) { - promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__); - return; - } + aOwner->mActor->SendExecServiceWorkerOp(mArgs)->Then( + GetCurrentSerialEventTarget(), __func__, + [promise = std::move(mPromise)]( + PRemoteWorkerParent::ExecServiceWorkerOpPromise:: + ResolveOrRejectValue&& aResult) { + if (NS_WARN_IF(aResult.IsReject())) { + promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__); + return; + } - promise->Resolve(std::move(aResult.ResolveValue()), __func__); - }); - break; - } - default: { - // mNonLifeCycleOpController can be nullptr if the Worker is in "Killing." - // RemoteWorkerNonLifeCycleOpControllerChild switches to the Killed status - // earlier than RemoteWorkerChild since it switches the status on the - // worker thread, not the main thread. - if (!aOwner->mNonLifeCycleOpController) { - Cancel(); - return true; - } - if (!aOwner->mNonLifeCycleOpController->CanSend()) { - return false; - } - aOwner->mNonLifeCycleOpController->SendExecServiceWorkerOp(mArgs)->Then( - GetCurrentSerialEventTarget(), __func__, - [promise = std::move(mPromise)]( - PRemoteWorkerParent::ExecServiceWorkerOpPromise:: - ResolveOrRejectValue&& aResult) { - if (NS_WARN_IF(aResult.IsReject())) { - promise->Reject(NS_ERROR_DOM_ABORT_ERR, __func__); - return; - } + promise->Resolve(std::move(aResult.ResolveValue()), __func__); + }); - promise->Resolve(std::move(aResult.ResolveValue()), __func__); - }); - } - } return true; } diff --git a/dom/workers/remoteworkers/RemoteWorkerController.h b/dom/workers/remoteworkers/RemoteWorkerController.h index c60ce238f929..af53634abd2b 100644 --- a/dom/workers/remoteworkers/RemoteWorkerController.h +++ b/dom/workers/remoteworkers/RemoteWorkerController.h @@ -15,7 +15,6 @@ #include "mozilla/dom/DOMTypes.h" #include "mozilla/dom/ServiceWorkerOpArgs.h" #include "mozilla/dom/ServiceWorkerOpPromise.h" -#include "mozilla/dom/SharedWorkerOpArgs.h" namespace mozilla::dom { @@ -90,7 +89,6 @@ class FetchEventOpParent; class RemoteWorkerControllerParent; class RemoteWorkerData; class RemoteWorkerManager; -class RemoteWorkerNonLifeCycleOpControllerParent; class RemoteWorkerParent; class RemoteWorkerObserver { @@ -126,7 +124,6 @@ class RemoteWorkerController final { friend class RemoteWorkerControllerParent; friend class RemoteWorkerManager; friend class RemoteWorkerParent; - friend class RemoteWorkerNonLifeCycleOpControllerParent; public: NS_INLINE_DECL_REFCOUNTING(RemoteWorkerController) @@ -195,7 +192,6 @@ class RemoteWorkerController final { RefPtr mObserver; RefPtr mActor; - RefPtr mNonLifeCycleOpController; enum { ePending, diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.cpp b/dom/workers/remoteworkers/RemoteWorkerManager.cpp index 48231775fb73..81003d68318c 100644 --- a/dom/workers/remoteworkers/RemoteWorkerManager.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerManager.cpp @@ -12,10 +12,7 @@ #include "mozilla/ScopeExit.h" #include "mozilla/dom/ContentChild.h" // ContentChild::GetSingleton #include "mozilla/dom/ProcessIsolation.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerParent.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerChild.h" #include "mozilla/dom/RemoteWorkerController.h" -#include "mozilla/dom/RemoteWorkerNonLifeCycleOpControllerParent.h" #include "mozilla/dom/RemoteWorkerParent.h" #include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/BackgroundUtils.h" @@ -326,20 +323,7 @@ void RemoteWorkerManager::LaunchInternal( RefPtr workerActor = MakeAndAddRef(std::move(aKeepAlive)); - - mozilla::ipc::Endpoint parentEp; - mozilla::ipc::Endpoint childEp; - MOZ_ALWAYS_SUCCEEDS(PRemoteWorkerNonLifeCycleOpController::CreateEndpoints( - &parentEp, &childEp)); - - MOZ_ASSERT(!aController->mNonLifeCycleOpController); - aController->mNonLifeCycleOpController = - MakeAndAddRef(aController); - - parentEp.Bind(aController->mNonLifeCycleOpController); - - if (!aTargetActor->SendPRemoteWorkerConstructor(workerActor, aData, - std::move(childEp))) { + if (!aTargetActor->SendPRemoteWorkerConstructor(workerActor, aData)) { AsyncCreationFailed(aController); return; } diff --git a/dom/workers/remoteworkers/RemoteWorkerManager.h b/dom/workers/remoteworkers/RemoteWorkerManager.h index 3d0347448e60..4e5d71c95b83 100644 --- a/dom/workers/remoteworkers/RemoteWorkerManager.h +++ b/dom/workers/remoteworkers/RemoteWorkerManager.h @@ -19,7 +19,6 @@ namespace mozilla::dom { class RemoteWorkerController; class RemoteWorkerServiceParent; -class RemoteWorkerNonLifeCycleOpControllerParent; /** * PBackground instance that keeps tracks of RemoteWorkerServiceParent actors diff --git a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.cpp b/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.cpp deleted file mode 100644 index 6dd0e49caa6d..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "RemoteWorkerNonLifeCycleOpControllerChild.h" -#include "mozilla/dom/ServiceWorkerOp.h" -#include "mozilla/dom/SharedWorkerOp.h" -#include "mozilla/dom/WorkerCommon.h" -#include "mozilla/dom/WorkerPrivate.h" -#include "mozilla/dom/WorkerRef.h" - -namespace mozilla::dom { - -using remoteworker::Canceled; -using remoteworker::Killed; -using remoteworker::Running; - -/* static */ -RefPtr -RemoteWorkerNonLifeCycleOpControllerChild::Create() { - MOZ_ASSERT(!NS_IsMainThread()); - MOZ_ASSERT(GetCurrentThreadWorkerPrivate()); - - RefPtr actor = - MakeAndAddRef(); - return actor; -} - -RemoteWorkerNonLifeCycleOpControllerChild:: - RemoteWorkerNonLifeCycleOpControllerChild() - : mState(VariantType(), - "RemoteWorkerNonLifeCycleOpControllerChild") {} - -RemoteWorkerNonLifeCycleOpControllerChild:: - ~RemoteWorkerNonLifeCycleOpControllerChild() = default; - -void RemoteWorkerNonLifeCycleOpControllerChild::TransistionStateToCanceled() { - auto lock = mState.Lock(); - MOZ_ASSERT(lock->is()); - - /*Canceling pending/processing operations here*/ - - *lock = VariantType(); -} - -void RemoteWorkerNonLifeCycleOpControllerChild::TransistionStateToKilled() { - auto lock = mState.Lock(); - MOZ_ASSERT(lock->is()); - *lock = VariantType(); - if (!CanSend()) { - return; - } - Unused << SendTerminated(); -} - -void RemoteWorkerNonLifeCycleOpControllerChild::ErrorPropagation( - nsresult aError) { - if (!CanSend()) { - return; - } - Unused << SendError(aError); -} - -void RemoteWorkerNonLifeCycleOpControllerChild::StartOp( - RefPtr&& aOp) { - MOZ_ASSERT(aOp); - auto lock = mState.Lock(); - // ServiceWorkerOp/SharedWorkerOp handles the Canceled/Killed state cases. - aOp->Start(this, lock.ref()); -} - -IPCResult RemoteWorkerNonLifeCycleOpControllerChild::RecvExecOp( - SharedWorkerOpArgs&& aOpArgs) { - MOZ_ASSERT(aOpArgs.type() == - SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs); - StartOp(new SharedWorkerOp(std::move(aOpArgs))); - - return IPC_OK(); -} - -IPCResult RemoteWorkerNonLifeCycleOpControllerChild::RecvExecServiceWorkerOp( - ServiceWorkerOpArgs&& aOpArgs, ExecServiceWorkerOpResolver&& aResolve) { - MOZ_ASSERT( - aOpArgs.type() != - ServiceWorkerOpArgs::TParentToChildServiceWorkerFetchEventOpArgs, - "FetchEvent operations should be sent via PFetchEventOp(Proxy) actors!"); - - MOZ_ASSERT(aOpArgs.type() != - ServiceWorkerOpArgs::TServiceWorkerTerminateWorkerOpArgs, - "Terminate operations should be sent via PRemoteWorker actros!"); - - StartOp(ServiceWorkerOp::Create(std::move(aOpArgs), std::move(aResolve))); - return IPC_OK(); -} - -IPCResult RemoteWorkerNonLifeCycleOpControllerChild::RecvShutdown() { - return IPC_OK(); -} - -} // namespace mozilla::dom diff --git a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.h b/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.h deleted file mode 100644 index e0214e892179..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerChild.h +++ /dev/null @@ -1,57 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_RemoteWorkerNonLifeCycleOpControllerChild_h -#define mozilla_dom_RemoteWorkerNonLifeCycleOpControllerChild_h - -#include "mozilla/DataMutex.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerChild.h" -#include "mozilla/dom/RemoteWorkerOp.h" -#include "mozilla/dom/ServiceWorkerOpArgs.h" -#include "mozilla/dom/SharedWorkerOpArgs.h" -#include "nsISupportsImpl.h" - -using mozilla::ipc::IPCResult; - -namespace mozilla::dom { - -using remoteworker::RemoteWorkerState; - -class ServiceWorkerOp; - -class RemoteWorkerNonLifeCycleOpControllerChild final - : public PRemoteWorkerNonLifeCycleOpControllerChild { - friend class PRemoteWorkerNonLifeCycleOpControllerChild; - friend class ServiceWorkerOp; - - public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING( - RemoteWorkerNonLifeCycleOpControllerChild, final) - - static RefPtr Create(); - - RemoteWorkerNonLifeCycleOpControllerChild(); - - IPCResult RecvExecOp(SharedWorkerOpArgs&& aOpArgs); - - IPCResult RecvExecServiceWorkerOp(ServiceWorkerOpArgs&& aOpArgs, - ExecServiceWorkerOpResolver&& aResolve); - - IPCResult RecvShutdown(); - - void TransistionStateToCanceled(); - void TransistionStateToKilled(); - - void ErrorPropagation(nsresult aError); - - private: - void StartOp(RefPtr&& aOp); - ~RemoteWorkerNonLifeCycleOpControllerChild(); - - DataMutex mState; -}; - -} // namespace mozilla::dom - -#endif // mozilla_dom_RemoteWorkerNonLifeCycleOpControllerChild_h diff --git a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.cpp b/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.cpp deleted file mode 100644 index 22bedccb81fc..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "RemoteWorkerNonLifeCycleOpControllerParent.h" -#include "mozilla/dom/RemoteWorkerController.h" - -namespace mozilla::dom { - -RemoteWorkerNonLifeCycleOpControllerParent:: - RemoteWorkerNonLifeCycleOpControllerParent( - RemoteWorkerController* aController) - : mController(aController) { - MOZ_ASSERT(mController); -} - -RemoteWorkerNonLifeCycleOpControllerParent:: - ~RemoteWorkerNonLifeCycleOpControllerParent() = default; - -void RemoteWorkerNonLifeCycleOpControllerParent::Shutdown() { - if (CanSend()) { - Unused << SendShutdown(); - } - mController = nullptr; -} - -IPCResult RemoteWorkerNonLifeCycleOpControllerParent::RecvTerminated() { - // mController could be nullptr when the controller had already shutted down. - if (mController) { - mController->mNonLifeCycleOpController = nullptr; - mController = nullptr; - } - - return IPC_OK(); -} - -IPCResult RemoteWorkerNonLifeCycleOpControllerParent::RecvError( - const ErrorValue& aError) { - MOZ_ASSERT(mController); - mController->ErrorPropagation(aError); - return IPC_OK(); -} - -void RemoteWorkerNonLifeCycleOpControllerParent::ActorDestroy( - IProtocol::ActorDestroyReason) { - if (mController) { - mController->mNonLifeCycleOpController = nullptr; - mController = nullptr; - } -} - -} // namespace mozilla::dom diff --git a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.h b/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.h deleted file mode 100644 index a25dd4c61e11..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerNonLifeCycleOpControllerParent.h +++ /dev/null @@ -1,41 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_RemoteWorkerNonLifeCycleOpControllerParent_h -#define mozilla_dom_RemoteWorkerNonLifeCycleOpControllerParent_h - -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerParent.h" - -using mozilla::ipc::IPCResult; - -namespace mozilla::dom { - -class RemoteWorkerController; - -class RemoteWorkerNonLifeCycleOpControllerParent final - : public PRemoteWorkerNonLifeCycleOpControllerParent { - public: - NS_INLINE_DECL_REFCOUNTING(RemoteWorkerNonLifeCycleOpControllerParent, - override); - - explicit RemoteWorkerNonLifeCycleOpControllerParent( - RemoteWorkerController* aRemoteWorkerController); - - IPCResult RecvTerminated(); - - IPCResult RecvError(const ErrorValue& aError); - - void ActorDestroy(IProtocol::ActorDestroyReason) override; - - void Shutdown(); - - private: - ~RemoteWorkerNonLifeCycleOpControllerParent(); - - RefPtr mController; -}; - -} // namespace mozilla::dom - -#endif // mozilla_dom_RemoteWorkerNonLifeCycleOpControllerParent_h diff --git a/dom/workers/remoteworkers/RemoteWorkerOp.cpp b/dom/workers/remoteworkers/RemoteWorkerOp.cpp deleted file mode 100644 index 313a9a587e04..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerOp.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "RemoteWorkerOp.h" - -namespace mozilla::dom::remoteworker { - -WorkerPrivateAccessibleState::~WorkerPrivateAccessibleState() { - // We should now only be performing state transitions on the main thread, so - // we should assert we're only releasing on the main thread. - MOZ_ASSERT(!mWorkerPrivate || NS_IsMainThread()); - // mWorkerPrivate can be safely released on the main thread. - if (!mWorkerPrivate || NS_IsMainThread()) { - return; - } - // But as a backstop, do proxy the release to the main thread. - NS_ReleaseOnMainThread( - "RemoteWorkerChild::WorkerPrivateAccessibleState::mWorkerPrivate", - mWorkerPrivate.forget()); -} - -} // namespace mozilla::dom::remoteworker diff --git a/dom/workers/remoteworkers/RemoteWorkerOp.h b/dom/workers/remoteworkers/RemoteWorkerOp.h deleted file mode 100644 index c4056205ce4d..000000000000 --- a/dom/workers/remoteworkers/RemoteWorkerOp.h +++ /dev/null @@ -1,95 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_RemoteWorkerOp_h -#define mozilla_dom_RemoteWorkerOp_h - -#include "mozilla/RefPtr.h" -#include "mozilla/dom/WorkerPrivate.h" -#include "mozilla/Variant.h" - -namespace mozilla::dom { - -class RemoteWorkerChild; -class RemtoeWorkerNonfLifeCycleOpControllerChild; -class RemoteWorkerOp; -// class RemoteWorkerNonLifeCycleOpControllerChild; - -namespace remoteworker { - -struct WorkerPrivateAccessibleState { - ~WorkerPrivateAccessibleState(); - RefPtr mWorkerPrivate; -}; - -// Initial state, mWorkerPrivate is initially null but will be initialized on -// the main thread by ExecWorkerOnMainThread when the WorkerPrivate is -// created. The state will transition to Running or Canceled, also from the -// main thread. -struct Pending : WorkerPrivateAccessibleState { - nsTArray> mPendingOps; -}; - -// Running, with the state transition happening on the main thread as a result -// of the worker successfully processing our initialization runnable, -// indicating that top-level script execution successfully completed. Because -// all of our state transitions happen on the main thread and are posed in -// terms of the main thread's perspective of the worker's state, it's very -// possible for us to skip directly from Pending to Canceled because we decide -// to cancel/terminate the worker prior to it finishing script loading or -// reporting back to us. -struct Running : WorkerPrivateAccessibleState {}; - -// Cancel() has been called on the WorkerPrivate on the main thread by a -// TerminationOp, top-level script evaluation has failed and canceled the -// worker, or in the case of a SharedWorker, close() has been called on -// the global scope by content code and the worker has advanced to the -// Canceling state. (Dedicated Workers can also self close, but they will -// never be RemoteWorkers. Although a SharedWorker can own DedicatedWorkers.) -// Browser shutdown will result in a TerminationOp thanks to use of a shutdown -// blocker in the parent, so the RuntimeService shouldn't get involved, but we -// would also handle that case acceptably too. -// -// Because worker self-closing is still handled by dispatching a runnable to -// the main thread to effectively call WorkerPrivate::Cancel(), there isn't -// a race between a worker deciding to self-close and our termination ops. -// -// In this state, we have dropped the reference to the WorkerPrivate and will -// no longer be dispatching runnables to the worker. We wait in this state -// until the termination lambda is invoked letting us know that the worker has -// entirely shutdown and we can advanced to the Killed state. -struct Canceled {}; - -// The worker termination lambda has been invoked and we know the Worker is -// entirely shutdown. (Inherently it is possible for us to advance to this -// state while the nsThread for the worker is still in the process of -// shutting down, but no more worker code will run on it.) -// -// This name is chosen to match the Worker's own state model. -struct Killed {}; - -using RemoteWorkerState = Variant; - -} // namespace remoteworker - -class RemoteWorkerOp { - public: - NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING - - virtual ~RemoteWorkerOp() = default; - - virtual bool MaybeStart(RemoteWorkerChild* aOwner, - remoteworker::RemoteWorkerState& aState) = 0; - - virtual void StartOnMainThread(RefPtr& aOwner) = 0; - - virtual void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, - remoteworker::RemoteWorkerState& aState) = 0; - - virtual void Cancel() = 0; -}; - -} // namespace mozilla::dom - -#endif diff --git a/dom/workers/remoteworkers/RemoteWorkerServiceChild.cpp b/dom/workers/remoteworkers/RemoteWorkerServiceChild.cpp index 5e43ce876906..ec6a848cc2a5 100644 --- a/dom/workers/remoteworkers/RemoteWorkerServiceChild.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerServiceChild.cpp @@ -16,18 +16,14 @@ RemoteWorkerServiceChild::~RemoteWorkerServiceChild() = default; already_AddRefed RemoteWorkerServiceChild::AllocPRemoteWorkerChild( - const RemoteWorkerData& aData, - mozilla::ipc::Endpoint& - aChildEp) { + const RemoteWorkerData& aData) { return MakeAndAddRef(aData); } mozilla::ipc::IPCResult RemoteWorkerServiceChild::RecvPRemoteWorkerConstructor( - PRemoteWorkerChild* aActor, const RemoteWorkerData& aData, - mozilla::ipc::Endpoint&& - aChildEp) { + PRemoteWorkerChild* aActor, const RemoteWorkerData& aData) { RemoteWorkerChild* actor = static_cast(aActor); - actor->ExecWorker(aData, std::move(aChildEp)); + actor->ExecWorker(aData); return IPC_OK(); } diff --git a/dom/workers/remoteworkers/RemoteWorkerServiceChild.h b/dom/workers/remoteworkers/RemoteWorkerServiceChild.h index 5633f3996bd2..c7bfbec253ae 100644 --- a/dom/workers/remoteworkers/RemoteWorkerServiceChild.h +++ b/dom/workers/remoteworkers/RemoteWorkerServiceChild.h @@ -8,7 +8,6 @@ #define mozilla_dom_RemoteWorkerServiceChild_h #include "mozilla/dom/PRemoteWorkerServiceChild.h" -#include "mozilla/dom/PRemoteWorkerNonLifeCycleOpControllerChild.h" #include "nsISupportsImpl.h" namespace mozilla::dom { @@ -27,14 +26,9 @@ class RemoteWorkerServiceChild final : public PRemoteWorkerServiceChild { RemoteWorkerServiceChild(); already_AddRefed AllocPRemoteWorkerChild( - const RemoteWorkerData& aData, - mozilla::ipc::Endpoint& - aChildEp); - + const RemoteWorkerData& aData); mozilla::ipc::IPCResult RecvPRemoteWorkerConstructor( - PRemoteWorkerChild* aActor, const RemoteWorkerData& aData, - mozilla::ipc::Endpoint&& - aChildEp); + PRemoteWorkerChild* aActor, const RemoteWorkerData& aData); private: ~RemoteWorkerServiceChild(); diff --git a/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp b/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp index be3ae00c3881..575b0e71ce64 100644 --- a/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp +++ b/dom/workers/remoteworkers/RemoteWorkerServiceParent.cpp @@ -6,8 +6,6 @@ #include "RemoteWorkerServiceParent.h" #include "RemoteWorkerManager.h" -#include "RemoteWorkerParent.h" -#include "mozilla/dom/RemoteWorkerTypes.h" #include "mozilla/ipc/BackgroundParent.h" namespace mozilla { diff --git a/dom/workers/remoteworkers/moz.build b/dom/workers/remoteworkers/moz.build index cc8917d9941a..9983b7dd1015 100644 --- a/dom/workers/remoteworkers/moz.build +++ b/dom/workers/remoteworkers/moz.build @@ -10,9 +10,6 @@ EXPORTS.mozilla.dom += [ "RemoteWorkerControllerChild.h", "RemoteWorkerControllerParent.h", "RemoteWorkerManager.h", - "RemoteWorkerNonLifeCycleOpControllerChild.h", - "RemoteWorkerNonLifeCycleOpControllerParent.h", - "RemoteWorkerOp.h", "RemoteWorkerParent.h", "RemoteWorkerService.h", "RemoteWorkerServiceChild.h", @@ -25,9 +22,6 @@ UNIFIED_SOURCES += [ "RemoteWorkerControllerChild.cpp", "RemoteWorkerControllerParent.cpp", "RemoteWorkerManager.cpp", - "RemoteWorkerNonLifeCycleOpControllerChild.cpp", - "RemoteWorkerNonLifeCycleOpControllerParent.cpp", - "RemoteWorkerOp.cpp", "RemoteWorkerParent.cpp", "RemoteWorkerService.cpp", "RemoteWorkerServiceChild.cpp", @@ -42,7 +36,6 @@ LOCAL_INCLUDES += [ IPDL_SOURCES += [ "PRemoteWorker.ipdl", "PRemoteWorkerController.ipdl", - "PRemoteWorkerNonLifeCycleOpController.ipdl", "PRemoteWorkerService.ipdl", "RemoteWorkerTypes.ipdlh", ] diff --git a/dom/workers/sharedworkers/SharedWorkerOp.cpp b/dom/workers/sharedworkers/SharedWorkerOp.cpp deleted file mode 100644 index ac96e09a4d8f..000000000000 --- a/dom/workers/sharedworkers/SharedWorkerOp.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "SharedWorkerOp.h" -#include "mozilla/dom/MessagePort.h" -#include "mozilla/dom/RemoteWorkerChild.h" -#include "mozilla/dom/RemoteWorkerNonLifeCycleOpControllerChild.h" -#include "mozilla/dom/WorkerPrivate.h" -#include "mozilla/dom/WorkerRunnable.h" -#include "mozilla/dom/WorkerScope.h" - -namespace mozilla::dom { - -using remoteworker::Canceled; -using remoteworker::Killed; -using remoteworker::Pending; -using remoteworker::Running; - -namespace { - -// Normal runnable because AddPortIdentifier() is going to exec JS code. -class MessagePortIdentifierRunnable final : public WorkerSameThreadRunnable { - public: - MessagePortIdentifierRunnable( - RemoteWorkerNonLifeCycleOpControllerChild* aActor, - const MessagePortIdentifier& aPortIdentifier) - : WorkerSameThreadRunnable("MessagePortIdentifierRunnable"), - mActor(aActor), - mPortIdentifier(aPortIdentifier) {} - - private: - bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { - if (aWorkerPrivate->GlobalScope()->IsDying()) { - mPortIdentifier.ForceClose(); - return true; - } - if (!aWorkerPrivate->ConnectMessagePort(aCx, mPortIdentifier)) { - mActor->ErrorPropagation(NS_ERROR_FAILURE); - } - return true; - } - - RefPtr mActor; - UniqueMessagePortId mPortIdentifier; -}; - -} // namespace - -SharedWorkerOp::SharedWorkerOp(SharedWorkerOpArgs&& aArgs) - : mOpArgs(std::move(aArgs)) {} - -SharedWorkerOp::~SharedWorkerOp() { MOZ_ASSERT(mStarted); } - -void SharedWorkerOp::Cancel() { -#ifdef DEBUG - mStarted = true; -#endif -} - -bool SharedWorkerOp::MaybeStart(RemoteWorkerChild* aOwner, - RemoteWorkerState& aState) { - MOZ_ASSERT(!mStarted); - MOZ_ASSERT(aOwner); - // Thread: We are on the Worker Launcher thread. - - // Return false, indicating we should queue this op if our current state is - // pending and this isn't a termination op (which should skip the line). - if (aState.is() && !IsTerminationOp()) { - return false; - } - - // If the worker is already shutting down (which should be unexpected - // because we should be told new operations after a termination op), just - // return true to indicate the op should be discarded. - if (aState.is() || aState.is()) { -#ifdef DEBUG - mStarted = true; -#endif - return true; - } - - MOZ_ASSERT(aState.is() || IsTerminationOp()); - - RefPtr self = this; - RefPtr owner = aOwner; - - nsCOMPtr r = NS_NewRunnableFunction( - __func__, [self = std::move(self), owner = std::move(owner)]() mutable { - { - auto lock = owner->mState.Lock(); - - if (NS_WARN_IF(lock->is() || lock->is())) { - self->Cancel(); - return; - } - } - - self->StartOnMainThread(owner); - }); - - MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r.forget())); - -#ifdef DEBUG - mStarted = true; -#endif - - return true; -} - -void SharedWorkerOp::StartOnMainThread(RefPtr& aOwner) { - AssertIsOnMainThread(); - - if (IsTerminationOp()) { - aOwner->CloseWorkerOnMainThread(); - return; - } - - auto lock = aOwner->mState.Lock(); - MOZ_ASSERT(lock->is()); - if (!lock->is()) { - aOwner->ErrorPropagationDispatch(NS_ERROR_DOM_INVALID_STATE_ERR); - return; - } - - RefPtr workerPrivate = lock->as().mWorkerPrivate; - - MOZ_ASSERT(workerPrivate); - - if (mOpArgs.type() == SharedWorkerOpArgs::TSharedWorkerSuspendOpArgs) { - workerPrivate->ParentWindowPaused(); - } else if (mOpArgs.type() == SharedWorkerOpArgs::TSharedWorkerResumeOpArgs) { - workerPrivate->ParentWindowResumed(); - } else if (mOpArgs.type() == SharedWorkerOpArgs::TSharedWorkerFreezeOpArgs) { - workerPrivate->Freeze(nullptr); - } else if (mOpArgs.type() == SharedWorkerOpArgs::TSharedWorkerThawOpArgs) { - workerPrivate->Thaw(nullptr); - } else if (mOpArgs.type() == - SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs) { - MOZ_CRASH( - "PortIdentifierOpArgs should not be processed by " - "StartOnMainThread!!!"); - } else if (mOpArgs.type() == - SharedWorkerOpArgs::TSharedWorkerAddWindowIDOpArgs) { - aOwner->mWindowIDs.AppendElement( - mOpArgs.get_SharedWorkerAddWindowIDOpArgs().windowID()); - } else if (mOpArgs.type() == - SharedWorkerOpArgs::TSharedWorkerRemoveWindowIDOpArgs) { - aOwner->mWindowIDs.RemoveElement( - mOpArgs.get_SharedWorkerRemoveWindowIDOpArgs().windowID()); - } else { - MOZ_CRASH("Unknown SharedWorkerOpArgs type!"); - } -} - -void SharedWorkerOp::Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, - RemoteWorkerState& aState) { - MOZ_ASSERT(!mStarted); - MOZ_ASSERT(aOwner); - // Thread: We are on the Worker thread. - - // Only PortIdentifierOp is NonLifeCycle related opertaion. - MOZ_ASSERT(mOpArgs.type() == - SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs); - - // Should never be Pending state. - MOZ_ASSERT(!aState.is()); - - // If the worker is already shutting down (which should be unexpected - // because we should be told new operations after a termination op), just - // return directly. - if (aState.is() || aState.is()) { -#ifdef DEBUG - mStarted = true; -#endif - MessagePort::ForceClose( - mOpArgs.get_SharedWorkerPortIdentifierOpArgs().portIdentifier()); - return; - } - - MOZ_ASSERT(aState.is()); - - // RefPtr workerPrivate = aState.as().mWorkerPrivate; - WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate(); - - RefPtr r = new MessagePortIdentifierRunnable( - aOwner, mOpArgs.get_SharedWorkerPortIdentifierOpArgs().portIdentifier()); - - if (NS_WARN_IF(!r->Dispatch(workerPrivate))) { - aOwner->ErrorPropagation(NS_ERROR_FAILURE); - } - -#ifdef DEBUG - mStarted = true; -#endif -} - -bool SharedWorkerOp::IsTerminationOp() const { - return mOpArgs.type() == SharedWorkerOpArgs::TSharedWorkerTerminateOpArgs; -} - -} // namespace mozilla::dom diff --git a/dom/workers/sharedworkers/SharedWorkerOp.h b/dom/workers/sharedworkers/SharedWorkerOp.h deleted file mode 100644 index 96fdc7e8ac77..000000000000 --- a/dom/workers/sharedworkers/SharedWorkerOp.h +++ /dev/null @@ -1,47 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_dom_sharedworkerop_h__ -#define mozilla_dom_sharedworkerop_h__ - -#include "mozilla/SchedulerGroup.h" - -#include "mozilla/dom/RemoteWorkerOp.h" -#include "mozilla/dom/SharedWorkerOpArgs.h" - -namespace mozilla::dom { - -using remoteworker::RemoteWorkerState; - -class SharedWorkerOp : public RemoteWorkerOp { - public: - NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerOp, override) - - explicit SharedWorkerOp(SharedWorkerOpArgs&& aArgs); - - bool MaybeStart(RemoteWorkerChild* aOwner, - RemoteWorkerState& aState) override; - - void StartOnMainThread(RefPtr& aOwner) final; - - void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner, - RemoteWorkerState& aState) final; - - void Cancel() override; - - private: - ~SharedWorkerOp(); - - bool IsTerminationOp() const; - - SharedWorkerOpArgs mOpArgs; - -#ifdef DEBUG - bool mStarted = false; -#endif -}; - -} // namespace mozilla::dom - -#endif diff --git a/dom/workers/sharedworkers/SharedWorkerOpArgs.ipdlh b/dom/workers/sharedworkers/SharedWorkerOpArgs.ipdlh deleted file mode 100644 index b70178768040..000000000000 --- a/dom/workers/sharedworkers/SharedWorkerOpArgs.ipdlh +++ /dev/null @@ -1,52 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -include DOMTypes; - -namespace mozilla { -namespace dom { - -struct SharedWorkerSuspendOpArgs -{}; - -struct SharedWorkerResumeOpArgs -{}; - -struct SharedWorkerFreezeOpArgs -{}; - -struct SharedWorkerThawOpArgs -{}; - -struct SharedWorkerTerminateOpArgs -{}; - -struct SharedWorkerPortIdentifierOpArgs -{ - MessagePortIdentifier portIdentifier; -}; - -struct SharedWorkerAddWindowIDOpArgs -{ - uint64_t windowID; -}; - -struct SharedWorkerRemoveWindowIDOpArgs -{ - uint64_t windowID; -}; - -union SharedWorkerOpArgs { - SharedWorkerSuspendOpArgs; - SharedWorkerResumeOpArgs; - SharedWorkerFreezeOpArgs; - SharedWorkerThawOpArgs; - SharedWorkerTerminateOpArgs; - SharedWorkerPortIdentifierOpArgs; - SharedWorkerAddWindowIDOpArgs; - SharedWorkerRemoveWindowIDOpArgs; -}; - -} // namespace dom -} // namespace mozilla diff --git a/dom/workers/sharedworkers/moz.build b/dom/workers/sharedworkers/moz.build index 5731e85b865f..2b83bc9525a8 100644 --- a/dom/workers/sharedworkers/moz.build +++ b/dom/workers/sharedworkers/moz.build @@ -8,7 +8,6 @@ EXPORTS.mozilla.dom += [ "SharedWorker.h", "SharedWorkerChild.h", "SharedWorkerManager.h", - "SharedWorkerOp.h", "SharedWorkerParent.h", ] @@ -16,14 +15,12 @@ UNIFIED_SOURCES += [ "SharedWorker.cpp", "SharedWorkerChild.cpp", "SharedWorkerManager.cpp", - "SharedWorkerOp.cpp", "SharedWorkerParent.cpp", "SharedWorkerService.cpp", ] IPDL_SOURCES += [ "PSharedWorker.ipdl", - "SharedWorkerOpArgs.ipdlh", ] include("/ipc/chromium/chromium-config.mozbuild") diff --git a/ipc/glue/BackgroundChildImpl.cpp b/ipc/glue/BackgroundChildImpl.cpp index 8fc7d0ef4a5f..5da245f08c21 100644 --- a/ipc/glue/BackgroundChildImpl.cpp +++ b/ipc/glue/BackgroundChildImpl.cpp @@ -27,6 +27,7 @@ #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h" #include "mozilla/dom/indexedDB/ThreadLocal.h" #include "mozilla/dom/quota/PQuotaChild.h" +#include "mozilla/dom/RemoteWorkerChild.h" #include "mozilla/dom/RemoteWorkerControllerChild.h" #include "mozilla/dom/RemoteWorkerServiceChild.h" #include "mozilla/dom/ServiceWorkerChild.h"