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