Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #include "MessagePortParent.h"
7 : #include "MessagePortService.h"
8 : #include "SharedMessagePortMessage.h"
9 : #include "mozilla/Unused.h"
10 :
11 : namespace mozilla {
12 : namespace dom {
13 :
14 0 : MessagePortParent::MessagePortParent(const nsID& aUUID)
15 : : mService(MessagePortService::GetOrCreate())
16 : , mUUID(aUUID)
17 : , mEntangled(false)
18 0 : , mCanSendData(true)
19 : {
20 0 : MOZ_ASSERT(mService);
21 0 : }
22 :
23 0 : MessagePortParent::~MessagePortParent()
24 : {
25 0 : MOZ_ASSERT(!mService);
26 0 : MOZ_ASSERT(!mEntangled);
27 0 : }
28 :
29 : bool
30 0 : MessagePortParent::Entangle(const nsID& aDestinationUUID,
31 : const uint32_t& aSequenceID)
32 : {
33 0 : if (!mService) {
34 0 : NS_WARNING("Entangle is called after a shutdown!");
35 0 : return false;
36 : }
37 :
38 0 : MOZ_ASSERT(!mEntangled);
39 :
40 0 : return mService->RequestEntangling(this, aDestinationUUID, aSequenceID);
41 : }
42 :
43 : mozilla::ipc::IPCResult
44 0 : MessagePortParent::RecvPostMessages(nsTArray<ClonedMessageData>&& aMessages)
45 : {
46 : // This converts the object in a data struct where we have BlobImpls.
47 0 : FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
48 0 : if (NS_WARN_IF(
49 : !SharedMessagePortMessage::FromMessagesToSharedParent(aMessages,
50 : messages))) {
51 0 : return IPC_FAIL_NO_REASON(this);
52 : }
53 :
54 0 : if (!mEntangled) {
55 0 : return IPC_FAIL_NO_REASON(this);
56 : }
57 :
58 0 : if (!mService) {
59 0 : NS_WARNING("Entangle is called after a shutdown!");
60 0 : return IPC_FAIL_NO_REASON(this);
61 : }
62 :
63 0 : if (messages.IsEmpty()) {
64 0 : return IPC_FAIL_NO_REASON(this);
65 : }
66 :
67 0 : if (!mService->PostMessages(this, messages)) {
68 0 : return IPC_FAIL_NO_REASON(this);
69 : }
70 0 : return IPC_OK();
71 : }
72 :
73 : mozilla::ipc::IPCResult
74 0 : MessagePortParent::RecvDisentangle(nsTArray<ClonedMessageData>&& aMessages)
75 : {
76 : // This converts the object in a data struct where we have BlobImpls.
77 0 : FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
78 0 : if (NS_WARN_IF(
79 : !SharedMessagePortMessage::FromMessagesToSharedParent(aMessages,
80 : messages))) {
81 0 : return IPC_FAIL_NO_REASON(this);
82 : }
83 :
84 0 : if (!mEntangled) {
85 0 : return IPC_FAIL_NO_REASON(this);
86 : }
87 :
88 0 : if (!mService) {
89 0 : NS_WARNING("Entangle is called after a shutdown!");
90 0 : return IPC_FAIL_NO_REASON(this);
91 : }
92 :
93 0 : if (!mService->DisentanglePort(this, messages)) {
94 0 : return IPC_FAIL_NO_REASON(this);
95 : }
96 :
97 0 : CloseAndDelete();
98 0 : return IPC_OK();
99 : }
100 :
101 : mozilla::ipc::IPCResult
102 0 : MessagePortParent::RecvStopSendingData()
103 : {
104 0 : if (!mEntangled) {
105 0 : return IPC_OK();
106 : }
107 :
108 0 : mCanSendData = false;
109 0 : Unused << SendStopSendingDataConfirmed();
110 0 : return IPC_OK();
111 : }
112 :
113 : mozilla::ipc::IPCResult
114 0 : MessagePortParent::RecvClose()
115 : {
116 0 : if (mService) {
117 0 : MOZ_ASSERT(mEntangled);
118 :
119 0 : if (!mService->ClosePort(this)) {
120 0 : return IPC_FAIL_NO_REASON(this);
121 : }
122 :
123 0 : Close();
124 : }
125 :
126 0 : MOZ_ASSERT(!mEntangled);
127 :
128 0 : Unused << Send__delete__(this);
129 0 : return IPC_OK();
130 : }
131 :
132 : void
133 0 : MessagePortParent::ActorDestroy(ActorDestroyReason aWhy)
134 : {
135 0 : if (mService && mEntangled) {
136 : // When the last parent is deleted, this service is freed but this cannot
137 : // be done when the hashtables are written by CloseAll.
138 0 : RefPtr<MessagePortService> kungFuDeathGrip = mService;
139 0 : kungFuDeathGrip->ParentDestroy(this);
140 : }
141 0 : }
142 :
143 : bool
144 0 : MessagePortParent::Entangled(const nsTArray<ClonedMessageData>& aMessages)
145 : {
146 0 : MOZ_ASSERT(!mEntangled);
147 0 : mEntangled = true;
148 0 : return SendEntangled(aMessages);
149 : }
150 :
151 : void
152 0 : MessagePortParent::CloseAndDelete()
153 : {
154 0 : Close();
155 0 : Unused << Send__delete__(this);
156 0 : }
157 :
158 : void
159 0 : MessagePortParent::Close()
160 : {
161 0 : mService = nullptr;
162 0 : mEntangled = false;
163 0 : }
164 :
165 : /* static */ bool
166 0 : MessagePortParent::ForceClose(const nsID& aUUID,
167 : const nsID& aDestinationUUID,
168 : const uint32_t& aSequenceID)
169 : {
170 0 : MessagePortService* service = MessagePortService::Get();
171 0 : if (!service) {
172 0 : NS_WARNING("The service must exist if we want to close an existing MessagePort.");
173 0 : return false;
174 : }
175 :
176 0 : return service->ForceClose(aUUID, aDestinationUUID, aSequenceID);
177 : }
178 :
179 : } // namespace dom
180 : } // namespace mozilla
|