From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/serviceworkers/ServiceWorkerProxy.cpp | 122 ++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 dom/serviceworkers/ServiceWorkerProxy.cpp (limited to 'dom/serviceworkers/ServiceWorkerProxy.cpp') diff --git a/dom/serviceworkers/ServiceWorkerProxy.cpp b/dom/serviceworkers/ServiceWorkerProxy.cpp new file mode 100644 index 0000000000..aa6b77c1fa --- /dev/null +++ b/dom/serviceworkers/ServiceWorkerProxy.cpp @@ -0,0 +1,122 @@ +/* -*- 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 "ServiceWorkerProxy.h" +#include "ServiceWorkerCloneData.h" +#include "ServiceWorkerManager.h" +#include "ServiceWorkerParent.h" + +#include "mozilla/SchedulerGroup.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/dom/ClientState.h" +#include "mozilla/ipc/BackgroundParent.h" +#include "ServiceWorkerInfo.h" + +namespace mozilla::dom { + +using mozilla::ipc::AssertIsOnBackgroundThread; + +ServiceWorkerProxy::~ServiceWorkerProxy() { + // Any thread + MOZ_DIAGNOSTIC_ASSERT(!mActor); + MOZ_DIAGNOSTIC_ASSERT(!mInfo); +} + +void ServiceWorkerProxy::MaybeShutdownOnBGThread() { + AssertIsOnBackgroundThread(); + if (!mActor) { + return; + } + mActor->MaybeSendDelete(); +} + +void ServiceWorkerProxy::InitOnMainThread() { + AssertIsOnMainThread(); + + auto scopeExit = MakeScopeExit([&] { MaybeShutdownOnMainThread(); }); + + RefPtr swm = ServiceWorkerManager::GetInstance(); + NS_ENSURE_TRUE_VOID(swm); + + RefPtr reg = + swm->GetRegistration(mDescriptor.PrincipalInfo(), mDescriptor.Scope()); + NS_ENSURE_TRUE_VOID(reg); + + RefPtr info = reg->GetByDescriptor(mDescriptor); + NS_ENSURE_TRUE_VOID(info); + + scopeExit.release(); + + mInfo = new nsMainThreadPtrHolder( + "ServiceWorkerProxy::mInfo", info); +} + +void ServiceWorkerProxy::MaybeShutdownOnMainThread() { + AssertIsOnMainThread(); + + nsCOMPtr r = NewRunnableMethod( + __func__, this, &ServiceWorkerProxy::MaybeShutdownOnBGThread); + + MOZ_ALWAYS_SUCCEEDS(mEventTarget->Dispatch(r.forget(), NS_DISPATCH_NORMAL)); +} + +void ServiceWorkerProxy::StopListeningOnMainThread() { + AssertIsOnMainThread(); + mInfo = nullptr; +} + +ServiceWorkerProxy::ServiceWorkerProxy( + const ServiceWorkerDescriptor& aDescriptor) + : mEventTarget(GetCurrentSerialEventTarget()), mDescriptor(aDescriptor) {} + +void ServiceWorkerProxy::Init(ServiceWorkerParent* aActor) { + AssertIsOnBackgroundThread(); + MOZ_DIAGNOSTIC_ASSERT(aActor); + MOZ_DIAGNOSTIC_ASSERT(!mActor); + MOZ_DIAGNOSTIC_ASSERT(mEventTarget); + + mActor = aActor; + + // Note, this must be done from a separate Init() method and not in + // the constructor. If done from the constructor the runnable can + // execute, complete, and release its reference before the constructor + // returns. + nsCOMPtr r = NewRunnableMethod( + "ServiceWorkerProxy::Init", this, &ServiceWorkerProxy::InitOnMainThread); + MOZ_ALWAYS_SUCCEEDS( + SchedulerGroup::Dispatch(TaskCategory::Other, r.forget())); +} + +void ServiceWorkerProxy::RevokeActor(ServiceWorkerParent* aActor) { + AssertIsOnBackgroundThread(); + MOZ_DIAGNOSTIC_ASSERT(mActor); + MOZ_DIAGNOSTIC_ASSERT(mActor == aActor); + mActor = nullptr; + + nsCOMPtr r = NewRunnableMethod( + __func__, this, &ServiceWorkerProxy::StopListeningOnMainThread); + MOZ_ALWAYS_SUCCEEDS( + SchedulerGroup::Dispatch(TaskCategory::Other, r.forget())); +} + +void ServiceWorkerProxy::PostMessage(RefPtr&& aData, + const ClientInfo& aClientInfo, + const ClientState& aClientState) { + AssertIsOnBackgroundThread(); + RefPtr self = this; + nsCOMPtr r = NS_NewRunnableFunction( + __func__, + [self, data = std::move(aData), aClientInfo, aClientState]() mutable { + if (!self->mInfo) { + return; + } + self->mInfo->PostMessage(std::move(data), aClientInfo, aClientState); + }); + MOZ_ALWAYS_SUCCEEDS( + SchedulerGroup::Dispatch(TaskCategory::Other, r.forget())); +} + +} // namespace mozilla::dom -- cgit v1.2.3