mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1672493 - P4 Move ShareWorker Non-life cycle related operations from RemoteWorker to RemoteWorkerNonLifeCycleOpController. r=asuth
Depends on D198005 Differential Revision: https://phabricator.services.mozilla.com/D198022
This commit is contained in:
parent
1b65048112
commit
46942c1113
@ -54,6 +54,9 @@ class ServiceWorkerOp : public RemoteWorkerOp {
|
||||
|
||||
void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) final;
|
||||
|
||||
void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner,
|
||||
RemoteWorkerState& aState) final {}
|
||||
|
||||
void Cancel() final;
|
||||
|
||||
protected:
|
||||
|
@ -3389,9 +3389,8 @@ void WorkerPrivate::DoRunLoop(JSContext* aCx) {
|
||||
if (mChildEp.IsValid()) {
|
||||
mRemoteWorkerNonLifeCycleOpController =
|
||||
RemoteWorkerNonLifeCycleOpControllerChild::Create();
|
||||
if (mRemoteWorkerNonLifeCycleOpController) {
|
||||
mChildEp.Bind(mRemoteWorkerNonLifeCycleOpController);
|
||||
}
|
||||
MOZ_ASSERT_DEBUG_OR_FUZZING(mRemoteWorkerNonLifeCycleOpController);
|
||||
mChildEp.Bind(mRemoteWorkerNonLifeCycleOpController);
|
||||
}
|
||||
|
||||
// Now that we've done that, we can go ahead and set up our AutoJSAPI. We
|
||||
@ -5341,6 +5340,7 @@ bool WorkerPrivate::NotifyInternal(WorkerStatus aStatus) {
|
||||
|
||||
if (aStatus == Killing && mRemoteWorkerNonLifeCycleOpController) {
|
||||
mRemoteWorkerNonLifeCycleOpController->TransistionStateToKilled();
|
||||
mRemoteWorkerNonLifeCycleOpController = nullptr;
|
||||
}
|
||||
|
||||
// If the worker script never ran, or failed to compile, we don't need to do
|
||||
|
@ -2,6 +2,8 @@
|
||||
* 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 SharedWorkerOpArgs;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom{
|
||||
@ -13,9 +15,12 @@ protocol PRemoteWorkerNonLifeCycleOpController
|
||||
parent:
|
||||
async Terminated();
|
||||
|
||||
child:
|
||||
async Shutdown();
|
||||
async Error(ErrorValue aValue);
|
||||
|
||||
child:
|
||||
async ExecOp(SharedWorkerOpArgs aOpArgs);
|
||||
|
||||
async Shutdown();
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -811,14 +811,6 @@ void RemoteWorkerChild::ExceptionalErrorTransitionDuringExecWorker() {
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteWorkerChild::AddPortIdentifier(
|
||||
JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
UniqueMessagePortId& aPortIdentifier) {
|
||||
if (NS_WARN_IF(!aWorkerPrivate->ConnectMessagePort(aCx, aPortIdentifier))) {
|
||||
ErrorPropagationDispatch(NS_ERROR_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteWorkerChild::CancelAllPendingOps(RemoteWorkerState& aState) {
|
||||
MOZ_ASSERT(aState.is<Pending>());
|
||||
|
||||
|
@ -78,9 +78,6 @@ class RemoteWorkerChild final : public PRemoteWorkerChild {
|
||||
|
||||
void FlushReportsOnMainThread(nsIConsoleReportCollector* aReporter);
|
||||
|
||||
void AddPortIdentifier(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
|
||||
UniqueMessagePortId& aPortIdentifier);
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> GetTerminationPromise();
|
||||
|
||||
RefPtr<GenericPromise> MaybeSendSetServiceWorkerSkipWaitingFlag();
|
||||
|
@ -97,6 +97,7 @@ void RemoteWorkerController::CreationFailed() {
|
||||
|
||||
if (mState == eTerminated) {
|
||||
MOZ_ASSERT(!mActor);
|
||||
MOZ_ASSERT(!mNonLifeCycleOpController);
|
||||
MOZ_ASSERT(mPendingOps.IsEmpty());
|
||||
// Nothing to do.
|
||||
return;
|
||||
@ -113,12 +114,14 @@ 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();
|
||||
@ -181,7 +184,9 @@ void RemoteWorkerController::Shutdown() {
|
||||
CancelAllPendingOps();
|
||||
|
||||
if (mNonLifeCycleOpController) {
|
||||
Unused << mNonLifeCycleOpController->SendShutdown();
|
||||
if (mNonLifeCycleOpController->CanSend()) {
|
||||
Unused << mNonLifeCycleOpController->SendShutdown();
|
||||
}
|
||||
mNonLifeCycleOpController = nullptr;
|
||||
}
|
||||
|
||||
@ -390,7 +395,11 @@ bool RemoteWorkerController::PendingSharedWorkerOp::MaybeStart(
|
||||
Unused << aOwner->mActor->SendExecOp(SharedWorkerThawOpArgs());
|
||||
break;
|
||||
case ePortIdentifier:
|
||||
Unused << aOwner->mActor->SendExecOp(
|
||||
MOZ_ASSERT(aOwner->mNonLifeCycleOpController);
|
||||
if (!aOwner->mNonLifeCycleOpController->CanSend()) {
|
||||
return false;
|
||||
}
|
||||
Unused << aOwner->mNonLifeCycleOpController->SendExecOp(
|
||||
SharedWorkerPortIdentifierOpArgs(mPortIdentifier));
|
||||
break;
|
||||
case eAddWindowID:
|
||||
|
@ -357,7 +357,7 @@ void RemoteWorkerManager::LaunchInternal(
|
||||
|
||||
MOZ_ASSERT(!aController->mNonLifeCycleOpController);
|
||||
aController->mNonLifeCycleOpController =
|
||||
MakeAndAddRef<RemoteWorkerNonLifeCycleOpControllerParent>();
|
||||
MakeAndAddRef<RemoteWorkerNonLifeCycleOpControllerParent>(aController);
|
||||
|
||||
parentEp.Bind(aController->mNonLifeCycleOpController);
|
||||
|
||||
|
@ -3,7 +3,9 @@
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteWorkerNonLifeCycleOpControllerChild.h"
|
||||
#include "mozilla/dom/SharedWorkerOp.h"
|
||||
#include "mozilla/dom/WorkerCommon.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerRef.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
@ -43,8 +45,36 @@ void RemoteWorkerNonLifeCycleOpControllerChild::TransistionStateToCanceled() {
|
||||
void RemoteWorkerNonLifeCycleOpControllerChild::TransistionStateToKilled() {
|
||||
auto lock = mState.Lock();
|
||||
MOZ_ASSERT(lock->is<Canceled>());
|
||||
Unused << SendTerminated();
|
||||
*lock = VariantType<Killed>();
|
||||
if (!CanSend()) {
|
||||
return;
|
||||
}
|
||||
Unused << SendTerminated();
|
||||
}
|
||||
|
||||
void RemoteWorkerNonLifeCycleOpControllerChild::ErrorPropagation(
|
||||
nsresult aError) {
|
||||
if (!CanSend()) {
|
||||
return;
|
||||
}
|
||||
Unused << SendError(aError);
|
||||
}
|
||||
|
||||
void RemoteWorkerNonLifeCycleOpControllerChild::StartOp(
|
||||
RefPtr<RemoteWorkerOp>&& 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::RecvShutdown() {
|
||||
|
@ -30,12 +30,17 @@ class RemoteWorkerNonLifeCycleOpControllerChild final
|
||||
|
||||
RemoteWorkerNonLifeCycleOpControllerChild();
|
||||
|
||||
void TransistionStateToCanceled();
|
||||
void TransistionStateToKilled();
|
||||
IPCResult RecvExecOp(SharedWorkerOpArgs&& aOpArgs);
|
||||
|
||||
IPCResult RecvShutdown();
|
||||
|
||||
void TransistionStateToCanceled();
|
||||
void TransistionStateToKilled();
|
||||
|
||||
void ErrorPropagation(nsresult aError);
|
||||
|
||||
private:
|
||||
void StartOp(RefPtr<RemoteWorkerOp>&& aOp);
|
||||
~RemoteWorkerNonLifeCycleOpControllerChild();
|
||||
|
||||
DataMutex<RemoteWorkerState> mState;
|
||||
|
@ -8,13 +8,30 @@
|
||||
namespace mozilla::dom {
|
||||
|
||||
RemoteWorkerNonLifeCycleOpControllerParent::
|
||||
RemoteWorkerNonLifeCycleOpControllerParent() {}
|
||||
RemoteWorkerNonLifeCycleOpControllerParent(
|
||||
RemoteWorkerController* aController)
|
||||
: mController(aController) {
|
||||
MOZ_ASSERT(mController);
|
||||
}
|
||||
|
||||
RemoteWorkerNonLifeCycleOpControllerParent::
|
||||
~RemoteWorkerNonLifeCycleOpControllerParent() = default;
|
||||
|
||||
IPCResult RemoteWorkerNonLifeCycleOpControllerParent::RecvTerminated() {
|
||||
Unused << SendShutdown();
|
||||
|
||||
// mController could be nullptr when the controller had already shutted down.
|
||||
if (mController) {
|
||||
mController->mNonLifeCycleOpController = nullptr;
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
IPCResult RemoteWorkerNonLifeCycleOpControllerParent::RecvError(
|
||||
const ErrorValue& aError) {
|
||||
MOZ_ASSERT(mController);
|
||||
mController->ErrorPropagation(aError);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -11,18 +11,25 @@ using mozilla::ipc::IPCResult;
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class RemoteWorkerController;
|
||||
|
||||
class RemoteWorkerNonLifeCycleOpControllerParent final
|
||||
: public PRemoteWorkerNonLifeCycleOpControllerParent {
|
||||
public:
|
||||
NS_INLINE_DECL_REFCOUNTING(RemoteWorkerNonLifeCycleOpControllerParent,
|
||||
override);
|
||||
|
||||
RemoteWorkerNonLifeCycleOpControllerParent();
|
||||
explicit RemoteWorkerNonLifeCycleOpControllerParent(
|
||||
RemoteWorkerController* aRemoteWorkerController);
|
||||
|
||||
IPCResult RecvTerminated();
|
||||
|
||||
IPCResult RecvError(const ErrorValue& aError);
|
||||
|
||||
private:
|
||||
~RemoteWorkerNonLifeCycleOpControllerParent();
|
||||
|
||||
RefPtr<RemoteWorkerController> mController;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace mozilla::dom {
|
||||
|
||||
class RemoteWorkerChild;
|
||||
class RemtoeWorkerNonfLifeCycleOpControllerChild;
|
||||
class RemoteWorkerOp;
|
||||
// class RemoteWorkerNonLifeCycleOpControllerChild;
|
||||
|
||||
@ -83,6 +84,9 @@ class RemoteWorkerOp {
|
||||
|
||||
virtual void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) = 0;
|
||||
|
||||
virtual void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner,
|
||||
remoteworker::RemoteWorkerState& aState) = 0;
|
||||
|
||||
virtual void Cancel() = 0;
|
||||
};
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#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"
|
||||
@ -13,15 +14,18 @@ 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 WorkerThreadRunnable {
|
||||
class MessagePortIdentifierRunnable final : public WorkerSameThreadRunnable {
|
||||
public:
|
||||
MessagePortIdentifierRunnable(RemoteWorkerChild* aActor,
|
||||
const MessagePortIdentifier& aPortIdentifier)
|
||||
: WorkerThreadRunnable("MessagePortIdentifierRunnable"),
|
||||
MessagePortIdentifierRunnable(
|
||||
RemoteWorkerNonLifeCycleOpControllerChild* aActor,
|
||||
const MessagePortIdentifier& aPortIdentifier)
|
||||
: WorkerSameThreadRunnable("MessagePortIdentifierRunnable"),
|
||||
mActor(aActor),
|
||||
mPortIdentifier(aPortIdentifier) {}
|
||||
|
||||
@ -31,11 +35,13 @@ class MessagePortIdentifierRunnable final : public WorkerThreadRunnable {
|
||||
mPortIdentifier.ForceClose();
|
||||
return true;
|
||||
}
|
||||
mActor->AddPortIdentifier(aCx, aWorkerPrivate, mPortIdentifier);
|
||||
if (!aWorkerPrivate->ConnectMessagePort(aCx, mPortIdentifier)) {
|
||||
mActor->ErrorPropagation(NS_ERROR_FAILURE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
RefPtr<RemoteWorkerChild> mActor;
|
||||
RefPtr<RemoteWorkerNonLifeCycleOpControllerChild> mActor;
|
||||
UniqueMessagePortId mPortIdentifier;
|
||||
};
|
||||
|
||||
@ -71,11 +77,6 @@ bool SharedWorkerOp::MaybeStart(RemoteWorkerChild* aOwner,
|
||||
#ifdef DEBUG
|
||||
mStarted = true;
|
||||
#endif
|
||||
if (mOpArgs.type() ==
|
||||
SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs) {
|
||||
MessagePort::ForceClose(
|
||||
mOpArgs.get_SharedWorkerPortIdentifierOpArgs().portIdentifier());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -91,13 +92,6 @@ bool SharedWorkerOp::MaybeStart(RemoteWorkerChild* aOwner,
|
||||
|
||||
if (NS_WARN_IF(lock->is<Canceled>() || lock->is<Killed>())) {
|
||||
self->Cancel();
|
||||
// Worker has already canceled, force close the MessagePort.
|
||||
if (self->mOpArgs.type() ==
|
||||
SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs) {
|
||||
MessagePort::ForceClose(
|
||||
self->mOpArgs.get_SharedWorkerPortIdentifierOpArgs()
|
||||
.portIdentifier());
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -143,12 +137,9 @@ void SharedWorkerOp::StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) {
|
||||
workerPrivate->Thaw(nullptr);
|
||||
} else if (mOpArgs.type() ==
|
||||
SharedWorkerOpArgs::TSharedWorkerPortIdentifierOpArgs) {
|
||||
RefPtr<MessagePortIdentifierRunnable> r = new MessagePortIdentifierRunnable(
|
||||
aOwner,
|
||||
mOpArgs.get_SharedWorkerPortIdentifierOpArgs().portIdentifier());
|
||||
if (NS_WARN_IF(!r->Dispatch(workerPrivate))) {
|
||||
aOwner->ErrorPropagationDispatch(NS_ERROR_FAILURE);
|
||||
}
|
||||
MOZ_CRASH(
|
||||
"PortIdentifierOpArgs should not be processed by "
|
||||
"StartOnMainThread!!!");
|
||||
} else if (mOpArgs.type() ==
|
||||
SharedWorkerOpArgs::TSharedWorkerAddWindowIDOpArgs) {
|
||||
aOwner->mWindowIDs.AppendElement(
|
||||
@ -162,6 +153,48 @@ void SharedWorkerOp::StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) {
|
||||
}
|
||||
}
|
||||
|
||||
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<Pending>());
|
||||
|
||||
// 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<Canceled>() || aState.is<Killed>()) {
|
||||
#ifdef DEBUG
|
||||
mStarted = true;
|
||||
#endif
|
||||
MessagePort::ForceClose(
|
||||
mOpArgs.get_SharedWorkerPortIdentifierOpArgs().portIdentifier());
|
||||
return;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aState.is<Running>());
|
||||
|
||||
// RefPtr<WorkerPrivate> workerPrivate = aState.as<Running>().mWorkerPrivate;
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
|
||||
RefPtr<MessagePortIdentifierRunnable> 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;
|
||||
}
|
||||
|
@ -25,6 +25,9 @@ class SharedWorkerOp : public RemoteWorkerOp {
|
||||
|
||||
void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) final;
|
||||
|
||||
void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner,
|
||||
RemoteWorkerState& aState) final;
|
||||
|
||||
void Cancel() override;
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user