Bug 1715547 - Remove ServiceWorkerContainer::Inner r=dom-worker-reviewers,asuth

Depends on D117344

Differential Revision: https://phabricator.services.mozilla.com/D138999
This commit is contained in:
Eden Chuang 2022-09-29 18:25:59 +00:00
Родитель eb9c853d1f
Коммит cac584a66d
7 изменённых файлов: 206 добавлений и 387 удалений

Просмотреть файл

@ -1,236 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "RemoteServiceWorkerContainerImpl.h"
#include <utility>
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "ServiceWorkerContainerChild.h"
namespace mozilla::dom {
using mozilla::ipc::BackgroundChild;
using mozilla::ipc::PBackgroundChild;
using mozilla::ipc::ResponseRejectReason;
RemoteServiceWorkerContainerImpl::~RemoteServiceWorkerContainerImpl() {
Shutdown();
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
}
void RemoteServiceWorkerContainerImpl::Shutdown() {
if (mShutdown) {
return;
}
mShutdown = true;
if (mActor) {
mActor->RevokeOwner(this);
mActor->MaybeStartTeardown();
mActor = nullptr;
}
}
void RemoteServiceWorkerContainerImpl::AddContainer(
ServiceWorkerContainer* aOuter) {
MOZ_DIAGNOSTIC_ASSERT(aOuter);
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
mOuter = aOuter;
}
void RemoteServiceWorkerContainerImpl::RemoveContainer(
ServiceWorkerContainer* aOuter) {
MOZ_DIAGNOSTIC_ASSERT(aOuter);
MOZ_DIAGNOSTIC_ASSERT(mOuter == aOuter);
mOuter = nullptr;
}
void RemoteServiceWorkerContainerImpl::Register(
const ClientInfo& aClientInfo, const nsACString& aScopeURL,
const nsACString& aScriptURL, ServiceWorkerUpdateViaCache aUpdateViaCache,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const {
if (!mActor) {
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Can't register service worker");
aFailureCB(std::move(rv));
return;
}
mActor->SendRegister(
aClientInfo.ToIPC(), nsCString(aScopeURL), nsCString(aScriptURL),
aUpdateViaCache,
[successCB = std::move(aSuccessCB), aFailureCB](
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
aFailureCB(CopyableErrorResult(rv));
return;
}
// success
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Failed to register service worker");
aFailureCB(std::move(rv));
});
}
void RemoteServiceWorkerContainerImpl::GetRegistration(
const ClientInfo& aClientInfo, const nsACString& aURL,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendGetRegistration(
aClientInfo.ToIPC(), nsCString(aURL),
[successCB = std::move(aSuccessCB), aFailureCB](
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
auto& rv = aResult.get_CopyableErrorResult();
// If rv is a failure then this is an application layer error. Note,
// though, we also reject with NS_OK to indicate that we just didn't
// find a registration.
aFailureCB(CopyableErrorResult(rv));
return;
}
// success
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerContainerImpl::GetRegistrations(
const ClientInfo& aClientInfo,
ServiceWorkerRegistrationListCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendGetRegistrations(
aClientInfo.ToIPC(),
[successCB = std::move(aSuccessCB), aFailureCB](
const IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
aFailureCB(CopyableErrorResult(rv));
return;
}
// success
auto& ipcList =
aResult.get_IPCServiceWorkerRegistrationDescriptorList();
nsTArray<ServiceWorkerRegistrationDescriptor> list(
ipcList.values().Length());
for (auto& ipcDesc : ipcList.values()) {
list.AppendElement(ServiceWorkerRegistrationDescriptor(ipcDesc));
}
successCB(std::move(list));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
void RemoteServiceWorkerContainerImpl::GetReady(
const ClientInfo& aClientInfo,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const {
if (!mActor) {
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return;
}
mActor->SendGetReady(
aClientInfo.ToIPC(),
[successCB = std::move(aSuccessCB), aFailureCB](
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
aFailureCB(CopyableErrorResult(rv));
return;
}
// success
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
},
[aFailureCB](ResponseRejectReason&& aReason) {
// IPC layer error
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
}
RemoteServiceWorkerContainerImpl::RemoteServiceWorkerContainerImpl()
: mOuter(nullptr), mShutdown(false) {
PBackgroundChild* parentActor =
BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!parentActor)) {
Shutdown();
return;
}
RefPtr<ServiceWorkerContainerChild> actor =
ServiceWorkerContainerChild::Create();
if (NS_WARN_IF(!actor)) {
Shutdown();
return;
}
PServiceWorkerContainerChild* sentActor =
parentActor->SendPServiceWorkerContainerConstructor(actor);
if (NS_WARN_IF(!sentActor)) {
Shutdown();
return;
}
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
mActor = std::move(actor);
mActor->SetOwner(this);
}
void RemoteServiceWorkerContainerImpl::RevokeActor(
ServiceWorkerContainerChild* aActor) {
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
mActor->RevokeOwner(this);
mActor = nullptr;
mShutdown = true;
}
} // namespace mozilla::dom

Просмотреть файл

@ -1,61 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_remoteserviceworkercontainerimpl_h__
#define mozilla_dom_remoteserviceworkercontainerimpl_h__
#include "ServiceWorkerContainer.h"
namespace mozilla::dom {
class ServiceWorkerContainerChild;
class RemoteServiceWorkerContainerImpl final
: public ServiceWorkerContainer::Inner {
RefPtr<ServiceWorkerContainerChild> mActor;
ServiceWorkerContainer* mOuter;
bool mShutdown;
~RemoteServiceWorkerContainerImpl();
void Shutdown();
// ServiceWorkerContainer::Inner implementation
void AddContainer(ServiceWorkerContainer* aOuter) override;
void RemoveContainer(ServiceWorkerContainer* aOuter) override;
void Register(const ClientInfo& aClientInfo, const nsACString& aScopeURL,
const nsACString& aScriptURL,
ServiceWorkerUpdateViaCache aUpdateViaCache,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const override;
void GetRegistration(
const ClientInfo& aClientInfo, const nsACString& aURL,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const override;
void GetRegistrations(
const ClientInfo& aClientInfo,
ServiceWorkerRegistrationListCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const override;
void GetReady(const ClientInfo& aClientInfo,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const override;
public:
RemoteServiceWorkerContainerImpl();
void RevokeActor(ServiceWorkerContainerChild* aActor);
NS_INLINE_DECL_REFCOUNTING(RemoteServiceWorkerContainerImpl, override)
};
} // namespace mozilla::dom
#endif // mozilla_dom_remoteserviceworkercontainerimpl_h__

Просмотреть файл

@ -35,10 +35,12 @@
#include "mozilla/dom/RootedDictionary.h"
#include "mozilla/dom/ServiceWorker.h"
#include "mozilla/dom/ServiceWorkerContainerBinding.h"
#include "mozilla/dom/ServiceWorkerContainerChild.h"
#include "mozilla/dom/ServiceWorkerManager.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/ipc/BackgroundChild.h"
#include "mozilla/ipc/PBackgroundChild.h"
#include "RemoteServiceWorkerContainerImpl.h"
#include "ServiceWorker.h"
#include "ServiceWorkerRegistration.h"
#include "ServiceWorkerUtils.h"
@ -50,6 +52,10 @@
namespace mozilla::dom {
using mozilla::ipc::BackgroundChild;
using mozilla::ipc::PBackgroundChild;
using mozilla::ipc::ResponseRejectReason;
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ServiceWorkerContainer)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
@ -62,26 +68,44 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerContainer, DOMEventTargetHelper,
// static
already_AddRefed<ServiceWorkerContainer> ServiceWorkerContainer::Create(
nsIGlobalObject* aGlobal) {
RefPtr<Inner> inner = new RemoteServiceWorkerContainerImpl();
RefPtr<ServiceWorkerContainer> ref =
new ServiceWorkerContainer(aGlobal, inner.forget());
RefPtr<ServiceWorkerContainer> ref = new ServiceWorkerContainer(aGlobal);
return ref.forget();
}
ServiceWorkerContainer::ServiceWorkerContainer(
nsIGlobalObject* aGlobal,
already_AddRefed<ServiceWorkerContainer::Inner> aInner)
: DOMEventTargetHelper(aGlobal), mInner(aInner) {
mInner->AddContainer(this);
ServiceWorkerContainer::ServiceWorkerContainer(nsIGlobalObject* aGlobal)
: DOMEventTargetHelper(aGlobal), mShutdown(false) {
PBackgroundChild* parentActor =
BackgroundChild::GetOrCreateForCurrentThread();
if (NS_WARN_IF(!parentActor)) {
Shutdown();
return;
}
RefPtr<ServiceWorkerContainerChild> actor =
ServiceWorkerContainerChild::Create();
if (NS_WARN_IF(!actor)) {
Shutdown();
return;
}
PServiceWorkerContainerChild* sentActor =
parentActor->SendPServiceWorkerContainerConstructor(actor);
if (NS_WARN_IF(!sentActor)) {
Shutdown();
return;
}
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
mActor = std::move(actor);
mActor->SetOwner(this);
Maybe<ServiceWorkerDescriptor> controller = aGlobal->GetController();
if (controller.isSome()) {
mControllerWorker = aGlobal->GetOrCreateServiceWorker(controller.ref());
}
}
ServiceWorkerContainer::~ServiceWorkerContainer() {
mInner->RemoveContainer(this);
}
ServiceWorkerContainer::~ServiceWorkerContainer() { Shutdown(); }
void ServiceWorkerContainer::DisconnectFromOwner() {
mControllerWorker = nullptr;
@ -129,6 +153,15 @@ void ServiceWorkerContainer::ReceiveMessage(
}
}
void ServiceWorkerContainer::RevokeActor(ServiceWorkerContainerChild* aActor) {
MOZ_DIAGNOSTIC_ASSERT(mActor);
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
mActor->RevokeOwner(this);
mActor = nullptr;
mShutdown = true;
}
JSObject* ServiceWorkerContainer::WrapObject(
JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
return ServiceWorkerContainer_Binding::Wrap(aCx, this, aGivenProto);
@ -332,10 +365,29 @@ already_AddRefed<Promise> ServiceWorkerContainer::Register(
RefPtr<ServiceWorkerContainer> self = this;
mInner->Register(
clientInfo.ref(), cleanedScopeURL, cleanedScriptURL,
aOptions.mUpdateViaCache,
[self, outer](const ServiceWorkerRegistrationDescriptor& aDesc) {
if (!mActor) {
aRv.ThrowInvalidStateError("Can't register service worker");
return nullptr;
}
mActor->SendRegister(
clientInfo.ref().ToIPC(), nsCString(cleanedScopeURL),
nsCString(cleanedScriptURL), aOptions.mUpdateViaCache,
[self,
outer](const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
CopyableErrorResult rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
outer->MaybeReject(std::move(rv));
return;
}
// success
const auto& ipcDesc =
aResult.get_IPCServiceWorkerRegistrationDescriptor();
ErrorResult rv;
nsIGlobalObject* global = self->GetGlobalIfValid(rv);
if (rv.Failed()) {
@ -343,10 +395,16 @@ already_AddRefed<Promise> ServiceWorkerContainer::Register(
return;
}
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(aDesc);
global->GetOrCreateServiceWorkerRegistration(
ServiceWorkerRegistrationDescriptor(ipcDesc));
outer->MaybeResolve(reg);
},
[outer](ErrorResult&& aRv) { outer->MaybeReject(std::move(aRv)); });
[outer](ResponseRejectReason&& aReason) {
// IPC layer error
CopyableErrorResult rv;
rv.ThrowInvalidStateError("Failed to register service worker");
outer->MaybeReject(std::move(rv));
});
return outer.forget();
}
@ -382,10 +440,34 @@ already_AddRefed<Promise> ServiceWorkerContainer::GetRegistrations(
RefPtr<ServiceWorkerContainer> self = this;
mInner->GetRegistrations(
clientInfo.ref(),
[self,
outer](const nsTArray<ServiceWorkerRegistrationDescriptor>& aDescList) {
if (!mActor) {
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return outer.forget();
}
mActor->SendGetRegistrations(
clientInfo.ref().ToIPC(),
[self, outer](
const IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
const auto& rv = aResult.get_CopyableErrorResult();
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
outer->MaybeReject(CopyableErrorResult(rv));
return;
}
// success
const auto& ipcList =
aResult.get_IPCServiceWorkerRegistrationDescriptorList();
nsTArray<ServiceWorkerRegistrationDescriptor> list(
ipcList.values().Length());
for (const auto& ipcDesc : ipcList.values()) {
list.AppendElement(ServiceWorkerRegistrationDescriptor(ipcDesc));
}
ErrorResult rv;
nsIGlobalObject* global = self->GetGlobalIfValid(rv);
if (rv.Failed()) {
@ -393,7 +475,7 @@ already_AddRefed<Promise> ServiceWorkerContainer::GetRegistrations(
return;
}
nsTArray<RefPtr<ServiceWorkerRegistration>> regList;
for (auto& desc : aDescList) {
for (auto& desc : list) {
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(desc);
if (reg) {
@ -402,7 +484,10 @@ already_AddRefed<Promise> ServiceWorkerContainer::GetRegistrations(
}
outer->MaybeResolve(regList);
},
[self, outer](ErrorResult&& aRv) { outer->MaybeReject(std::move(aRv)); });
[outer](ResponseRejectReason&& aReason) {
// IPC layer error
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
});
return outer.forget();
}
@ -458,9 +543,38 @@ already_AddRefed<Promise> ServiceWorkerContainer::GetRegistration(
RefPtr<ServiceWorkerContainer> self = this;
mInner->GetRegistration(
clientInfo.ref(), spec,
[self, outer](const ServiceWorkerRegistrationDescriptor& aDescriptor) {
if (!mActor) {
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
return outer.forget();
}
mActor->SendGetRegistration(
clientInfo.ref().ToIPC(), spec,
[self,
outer](const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
CopyableErrorResult ipcRv(aResult.get_CopyableErrorResult());
ErrorResult rv(std::move(ipcRv));
if (!rv.Failed()) {
// ErrorResult rv;
// If rv is a failure then this is an application layer error.
// Note, though, we also reject with NS_OK to indicate that we just
// didn't find a registration.
Unused << self->GetGlobalIfValid(rv);
if (!rv.Failed()) {
outer->MaybeResolveWithUndefined();
return;
}
}
outer->MaybeReject(std::move(rv));
return;
}
// success
const auto& ipcDesc =
aResult.get_IPCServiceWorkerRegistrationDescriptor();
ErrorResult rv;
nsIGlobalObject* global = self->GetGlobalIfValid(rv);
if (rv.Failed()) {
@ -468,20 +582,14 @@ already_AddRefed<Promise> ServiceWorkerContainer::GetRegistration(
return;
}
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(aDescriptor);
global->GetOrCreateServiceWorkerRegistration(
ServiceWorkerRegistrationDescriptor(ipcDesc));
outer->MaybeResolve(reg);
},
[self, outer](ErrorResult&& aRv) {
if (!aRv.Failed()) {
Unused << self->GetGlobalIfValid(aRv);
if (!aRv.Failed()) {
outer->MaybeResolveWithUndefined();
return;
}
}
outer->MaybeReject(std::move(aRv));
[self, outer](ResponseRejectReason&& aReason) {
// IPC layer error
outer->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR);
});
return outer.forget();
}
@ -511,9 +619,29 @@ Promise* ServiceWorkerContainer::GetReady(ErrorResult& aRv) {
RefPtr<ServiceWorkerContainer> self = this;
RefPtr<Promise> outer = mReadyPromise;
mInner->GetReady(
clientInfo.ref(),
[self, outer](const ServiceWorkerRegistrationDescriptor& aDescriptor) {
if (!mActor) {
mReadyPromise->MaybeReject(
CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
return mReadyPromise;
}
mActor->SendGetReady(
clientInfo.ref().ToIPC(),
[self,
outer](const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
aResult) {
if (aResult.type() ==
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
TCopyableErrorResult) {
// application layer error
CopyableErrorResult rv(aResult.get_CopyableErrorResult());
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
outer->MaybeReject(std::move(rv));
return;
}
// success
const auto& ipcDesc =
aResult.get_IPCServiceWorkerRegistrationDescriptor();
ErrorResult rv;
nsIGlobalObject* global = self->GetGlobalIfValid(rv);
if (rv.Failed()) {
@ -521,17 +649,21 @@ Promise* ServiceWorkerContainer::GetReady(ErrorResult& aRv) {
return;
}
RefPtr<ServiceWorkerRegistration> reg =
global->GetOrCreateServiceWorkerRegistration(aDescriptor);
global->GetOrCreateServiceWorkerRegistration(
ServiceWorkerRegistrationDescriptor(ipcDesc));
NS_ENSURE_TRUE_VOID(reg);
// Don't resolve the ready promise until the registration has
// reached the right version. This ensures that the active
// worker property is set correctly on the registration.
reg->WhenVersionReached(
aDescriptor.Version(),
[outer, reg](bool aResult) { outer->MaybeResolve(reg); });
reg->WhenVersionReached(ipcDesc.version(), [outer, reg](bool aResult) {
outer->MaybeResolve(reg);
});
},
[self, outer](ErrorResult&& aRv) { outer->MaybeReject(std::move(aRv)); });
[outer](ResponseRejectReason&& aReason) {
// IPC layer error
outer->MaybeReject(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
});
return mReadyPromise;
}
@ -745,4 +877,17 @@ Result<Ok, bool> ServiceWorkerContainer::FillInMessageEventInit(
return Ok();
}
void ServiceWorkerContainer::Shutdown() {
if (mShutdown) {
return;
}
mShutdown = true;
if (mActor) {
mActor->RevokeOwner(this);
mActor->MaybeStartTeardown();
mActor = nullptr;
}
}
} // namespace mozilla::dom

Просмотреть файл

@ -20,40 +20,11 @@ struct MessageEventInit;
class Promise;
struct RegistrationOptions;
class ServiceWorker;
class ServiceWorkerContainerChild;
// Lightweight serviceWorker APIs collection.
class ServiceWorkerContainer final : public DOMEventTargetHelper {
public:
class Inner {
public:
virtual void AddContainer(ServiceWorkerContainer* aOuter) = 0;
virtual void RemoveContainer(ServiceWorkerContainer* aOuter) = 0;
virtual void Register(const ClientInfo& aClientInfo,
const nsACString& aScopeURL,
const nsACString& aScriptURL,
ServiceWorkerUpdateViaCache aUpdateViaCache,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const = 0;
virtual void GetRegistration(
const ClientInfo& aClientInfo, const nsACString& aURL,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const = 0;
virtual void GetRegistrations(
const ClientInfo& aClientInfo,
ServiceWorkerRegistrationListCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const = 0;
virtual void GetReady(const ClientInfo& aClientInfo,
ServiceWorkerRegistrationCallback&& aSuccessCB,
ServiceWorkerFailureCallback&& aFailureCB) const = 0;
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
};
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerContainer,
DOMEventTargetHelper)
@ -109,10 +80,10 @@ class ServiceWorkerContainer final : public DOMEventTargetHelper {
void ReceiveMessage(const ClientPostMessageArgs& aArgs);
void RevokeActor(ServiceWorkerContainerChild* aActor);
private:
ServiceWorkerContainer(
nsIGlobalObject* aGlobal,
already_AddRefed<ServiceWorkerContainer::Inner> aInner);
explicit ServiceWorkerContainer(nsIGlobalObject* aGlobal);
~ServiceWorkerContainer();
@ -147,7 +118,10 @@ class ServiceWorkerContainer final : public DOMEventTargetHelper {
MessageEventInit& aInit,
ErrorResult& aRv);
RefPtr<Inner> mInner;
void Shutdown();
RefPtr<ServiceWorkerContainerChild> mActor;
bool mShutdown;
// This only changes when a worker hijacks everything in its scope by calling
// claim.

Просмотреть файл

@ -8,7 +8,7 @@
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/WorkerRef.h"
#include "RemoteServiceWorkerContainerImpl.h"
#include "ServiceWorkerContainer.h"
#include "ServiceWorkerContainerChild.h"
namespace mozilla::dom {
@ -48,15 +48,13 @@ ServiceWorkerContainerChild::Create() {
ServiceWorkerContainerChild::ServiceWorkerContainerChild()
: mOwner(nullptr), mTeardownStarted(false) {}
void ServiceWorkerContainerChild::SetOwner(
RemoteServiceWorkerContainerImpl* aOwner) {
void ServiceWorkerContainerChild::SetOwner(ServiceWorkerContainer* aOwner) {
MOZ_DIAGNOSTIC_ASSERT(!mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner);
mOwner = aOwner;
}
void ServiceWorkerContainerChild::RevokeOwner(
RemoteServiceWorkerContainerImpl* aOwner) {
void ServiceWorkerContainerChild::RevokeOwner(ServiceWorkerContainer* aOwner) {
MOZ_DIAGNOSTIC_ASSERT(mOwner);
MOZ_DIAGNOSTIC_ASSERT(aOwner == mOwner);
mOwner = nullptr;

Просмотреть файл

@ -14,13 +14,13 @@
namespace mozilla::dom {
class RemoteServiceWorkerContainerImpl;
class ServiceWorkerContainer;
class IPCWorkerRef;
class ServiceWorkerContainerChild final : public PServiceWorkerContainerChild {
RefPtr<IPCWorkerRef> mIPCWorkerRef;
RemoteServiceWorkerContainerImpl* mOwner;
ServiceWorkerContainer* mOwner;
bool mTeardownStarted;
ServiceWorkerContainerChild();
@ -35,9 +35,9 @@ class ServiceWorkerContainerChild final : public PServiceWorkerContainerChild {
static already_AddRefed<ServiceWorkerContainerChild> Create();
void SetOwner(RemoteServiceWorkerContainerImpl* aOwner);
void SetOwner(ServiceWorkerContainer* aOwner);
void RevokeOwner(RemoteServiceWorkerContainerImpl* aOwner);
void RevokeOwner(ServiceWorkerContainer* aOwner);
void MaybeStartTeardown();
};

Просмотреть файл

@ -48,7 +48,6 @@ UNIFIED_SOURCES += [
"FetchEventOpProxyChild.cpp",
"FetchEventOpProxyParent.cpp",
"NavigationPreloadManager.cpp",
"RemoteServiceWorkerContainerImpl.cpp",
"RemoteServiceWorkerImpl.cpp",
"ServiceWorker.cpp",
"ServiceWorkerActors.cpp",