1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ServiceWorkerProxy.h"
8 #include "ServiceWorkerCloneData.h"
9 #include "ServiceWorkerManager.h"
10 #include "ServiceWorkerParent.h"
12 #include "mozilla/SchedulerGroup.h"
13 #include "mozilla/ScopeExit.h"
14 #include "mozilla/dom/ClientState.h"
15 #include "mozilla/ipc/BackgroundParent.h"
16 #include "ServiceWorkerInfo.h"
18 namespace mozilla::dom
{
20 using mozilla::ipc::AssertIsOnBackgroundThread
;
22 ServiceWorkerProxy::~ServiceWorkerProxy() {
24 MOZ_DIAGNOSTIC_ASSERT(!mActor
);
25 MOZ_DIAGNOSTIC_ASSERT(!mInfo
);
28 void ServiceWorkerProxy::MaybeShutdownOnBGThread() {
29 AssertIsOnBackgroundThread();
33 mActor
->MaybeSendDelete();
36 void ServiceWorkerProxy::InitOnMainThread() {
37 AssertIsOnMainThread();
39 auto scopeExit
= MakeScopeExit([&] { MaybeShutdownOnMainThread(); });
41 RefPtr
<ServiceWorkerManager
> swm
= ServiceWorkerManager::GetInstance();
42 NS_ENSURE_TRUE_VOID(swm
);
44 RefPtr
<ServiceWorkerRegistrationInfo
> reg
=
45 swm
->GetRegistration(mDescriptor
.PrincipalInfo(), mDescriptor
.Scope());
46 NS_ENSURE_TRUE_VOID(reg
);
48 RefPtr
<ServiceWorkerInfo
> info
= reg
->GetByDescriptor(mDescriptor
);
49 NS_ENSURE_TRUE_VOID(info
);
53 mInfo
= new nsMainThreadPtrHolder
<ServiceWorkerInfo
>(
54 "ServiceWorkerProxy::mInfo", info
);
57 void ServiceWorkerProxy::MaybeShutdownOnMainThread() {
58 AssertIsOnMainThread();
60 nsCOMPtr
<nsIRunnable
> r
= NewRunnableMethod(
61 __func__
, this, &ServiceWorkerProxy::MaybeShutdownOnBGThread
);
63 MOZ_ALWAYS_SUCCEEDS(mEventTarget
->Dispatch(r
.forget(), NS_DISPATCH_NORMAL
));
66 void ServiceWorkerProxy::StopListeningOnMainThread() {
67 AssertIsOnMainThread();
71 ServiceWorkerProxy::ServiceWorkerProxy(
72 const ServiceWorkerDescriptor
& aDescriptor
)
73 : mEventTarget(GetCurrentSerialEventTarget()), mDescriptor(aDescriptor
) {}
75 void ServiceWorkerProxy::Init(ServiceWorkerParent
* aActor
) {
76 AssertIsOnBackgroundThread();
77 MOZ_DIAGNOSTIC_ASSERT(aActor
);
78 MOZ_DIAGNOSTIC_ASSERT(!mActor
);
79 MOZ_DIAGNOSTIC_ASSERT(mEventTarget
);
83 // Note, this must be done from a separate Init() method and not in
84 // the constructor. If done from the constructor the runnable can
85 // execute, complete, and release its reference before the constructor
87 nsCOMPtr
<nsIRunnable
> r
= NewRunnableMethod(
88 "ServiceWorkerProxy::Init", this, &ServiceWorkerProxy::InitOnMainThread
);
89 MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r
.forget()));
92 void ServiceWorkerProxy::RevokeActor(ServiceWorkerParent
* aActor
) {
93 AssertIsOnBackgroundThread();
94 MOZ_DIAGNOSTIC_ASSERT(mActor
);
95 MOZ_DIAGNOSTIC_ASSERT(mActor
== aActor
);
98 nsCOMPtr
<nsIRunnable
> r
= NewRunnableMethod(
99 __func__
, this, &ServiceWorkerProxy::StopListeningOnMainThread
);
100 MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r
.forget()));
103 void ServiceWorkerProxy::PostMessage(RefPtr
<ServiceWorkerCloneData
>&& aData
,
104 const PostMessageSource
& aSource
) {
105 AssertIsOnBackgroundThread();
106 RefPtr
<ServiceWorkerProxy
> self
= this;
107 nsCOMPtr
<nsIRunnable
> r
= NS_NewRunnableFunction(
108 __func__
, [self
, data
= std::move(aData
), aSource
]() mutable {
112 self
->mInfo
->PostMessage(std::move(data
), aSource
);
114 MOZ_ALWAYS_SUCCEEDS(SchedulerGroup::Dispatch(r
.forget()));
117 } // namespace mozilla::dom