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/. */
6
7 #include "SharedWorkerParent.h"
8 #include "SharedWorkerManager.h"
9 #include "SharedWorkerService.h"
10 #include "mozilla/dom/RemoteWorkerTypes.h"
11 #include "mozilla/ipc/BackgroundParent.h"
12 #include "mozilla/ipc/BackgroundUtils.h"
13 #include "mozilla/Unused.h"
14
15 namespace mozilla {
16
17 using namespace ipc;
18
19 namespace dom {
20
SharedWorkerParent()21 SharedWorkerParent::SharedWorkerParent()
22 : mBackgroundEventTarget(GetCurrentEventTarget()),
23 mStatus(eInit),
24 mSuspended(false),
25 mFrozen(false) {
26 AssertIsOnBackgroundThread();
27 }
28
29 SharedWorkerParent::~SharedWorkerParent() = default;
30
ActorDestroy(IProtocol::ActorDestroyReason aReason)31 void SharedWorkerParent::ActorDestroy(IProtocol::ActorDestroyReason aReason) {
32 AssertIsOnBackgroundThread();
33
34 if (mWorkerManagerWrapper) {
35 mWorkerManagerWrapper->Manager()->RemoveActor(this);
36 mWorkerManagerWrapper = nullptr;
37 }
38 }
39
Initialize(const RemoteWorkerData & aData,uint64_t aWindowID,const MessagePortIdentifier & aPortIdentifier)40 void SharedWorkerParent::Initialize(
41 const RemoteWorkerData& aData, uint64_t aWindowID,
42 const MessagePortIdentifier& aPortIdentifier) {
43 AssertIsOnBackgroundThread();
44 MOZ_ASSERT(mStatus == eInit);
45
46 mWindowID = aWindowID;
47
48 mStatus = ePending;
49
50 RefPtr<SharedWorkerService> service = SharedWorkerService::GetOrCreate();
51 MOZ_ASSERT(service);
52 service->GetOrCreateWorkerManager(this, aData, aWindowID, aPortIdentifier);
53 }
54
RecvClose()55 IPCResult SharedWorkerParent::RecvClose() {
56 AssertIsOnBackgroundThread();
57 MOZ_ASSERT(mStatus == ePending || mStatus == eActive);
58
59 mStatus = eClosed;
60
61 if (mWorkerManagerWrapper) {
62 mWorkerManagerWrapper->Manager()->RemoveActor(this);
63 mWorkerManagerWrapper = nullptr;
64 }
65
66 Unused << Send__delete__(this);
67 return IPC_OK();
68 }
69
RecvSuspend()70 IPCResult SharedWorkerParent::RecvSuspend() {
71 AssertIsOnBackgroundThread();
72 MOZ_ASSERT(!mSuspended);
73 MOZ_ASSERT(mStatus == ePending || mStatus == eActive);
74
75 mSuspended = true;
76
77 if (mStatus == eActive) {
78 MOZ_ASSERT(mWorkerManagerWrapper);
79 mWorkerManagerWrapper->Manager()->UpdateSuspend();
80 }
81
82 return IPC_OK();
83 }
84
RecvResume()85 IPCResult SharedWorkerParent::RecvResume() {
86 AssertIsOnBackgroundThread();
87 MOZ_ASSERT(mSuspended);
88 MOZ_ASSERT(mStatus == ePending || mStatus == eActive);
89
90 mSuspended = false;
91
92 if (mStatus == eActive) {
93 MOZ_ASSERT(mWorkerManagerWrapper);
94 mWorkerManagerWrapper->Manager()->UpdateSuspend();
95 }
96
97 return IPC_OK();
98 }
99
RecvFreeze()100 IPCResult SharedWorkerParent::RecvFreeze() {
101 AssertIsOnBackgroundThread();
102 MOZ_ASSERT(!mFrozen);
103 MOZ_ASSERT(mStatus == ePending || mStatus == eActive);
104
105 mFrozen = true;
106
107 if (mStatus == eActive) {
108 MOZ_ASSERT(mWorkerManagerWrapper);
109 mWorkerManagerWrapper->Manager()->UpdateFrozen();
110 }
111
112 return IPC_OK();
113 }
114
RecvThaw()115 IPCResult SharedWorkerParent::RecvThaw() {
116 AssertIsOnBackgroundThread();
117 MOZ_ASSERT(mFrozen);
118 MOZ_ASSERT(mStatus == ePending || mStatus == eActive);
119
120 mFrozen = false;
121
122 if (mStatus == eActive) {
123 MOZ_ASSERT(mWorkerManagerWrapper);
124 mWorkerManagerWrapper->Manager()->UpdateFrozen();
125 }
126
127 return IPC_OK();
128 }
129
ManagerCreated(already_AddRefed<SharedWorkerManagerWrapper> aWorkerManagerWrapper)130 void SharedWorkerParent::ManagerCreated(
131 already_AddRefed<SharedWorkerManagerWrapper> aWorkerManagerWrapper) {
132 AssertIsOnBackgroundThread();
133 MOZ_ASSERT(!mWorkerManagerWrapper);
134 MOZ_ASSERT(mStatus == ePending || mStatus == eClosed);
135
136 RefPtr<SharedWorkerManagerWrapper> wrapper = aWorkerManagerWrapper;
137
138 // Already gone.
139 if (mStatus == eClosed) {
140 wrapper->Manager()->RemoveActor(this);
141 return;
142 }
143
144 mStatus = eActive;
145 mWorkerManagerWrapper = wrapper;
146
147 mWorkerManagerWrapper->Manager()->UpdateFrozen();
148 mWorkerManagerWrapper->Manager()->UpdateSuspend();
149 }
150
ErrorPropagation(nsresult aError)151 void SharedWorkerParent::ErrorPropagation(nsresult aError) {
152 AssertIsOnBackgroundThread();
153 MOZ_ASSERT(NS_FAILED(aError));
154 MOZ_ASSERT(mStatus == ePending || mStatus == eClosed);
155
156 // Already gone.
157 if (mStatus == eClosed) {
158 return;
159 }
160
161 Unused << SendError(aError);
162 }
163
164 } // namespace dom
165 } // namespace mozilla
166