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"