Bug 1769952 - Fix running raptor on a Win10-64 VM r=sparky
[gecko.git] / dom / messagechannel / MessagePortParent.cpp
blob846f1c2cda885e9ac302cd45c6d01b68cebfafc1
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 "MessagePortParent.h"
8 #include "MessagePortService.h"
9 #include "mozilla/dom/RefMessageBodyService.h"
10 #include "mozilla/dom/SharedMessageBody.h"
11 #include "mozilla/Unused.h"
13 namespace mozilla::dom {
15 MessagePortParent::MessagePortParent(const nsID& aUUID)
16 : mService(MessagePortService::GetOrCreate()),
17 mUUID(aUUID),
18 mEntangled(false),
19 mCanSendData(true) {
20 MOZ_ASSERT(mService);
23 MessagePortParent::~MessagePortParent() {
24 MOZ_ASSERT(!mService);
25 MOZ_ASSERT(!mEntangled);
28 bool MessagePortParent::Entangle(const nsID& aDestinationUUID,
29 const uint32_t& aSequenceID) {
30 if (!mService) {
31 NS_WARNING("Entangle is called after a shutdown!");
32 return false;
35 MOZ_ASSERT(!mEntangled);
37 return mService->RequestEntangling(this, aDestinationUUID, aSequenceID);
40 mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages(
41 nsTArray<MessageData>&& aMessages) {
42 if (!mService) {
43 NS_WARNING("PostMessages is called after a shutdown!");
44 // This implies most probably that CloseAndDelete() has been already called
45 // such that we have no better option than to silently ignore this call.
46 return IPC_OK();
49 if (!mEntangled) {
50 // If we were shut down, the above condition already bailed out. So this
51 // should actually never happen and returning a failure is fine.
52 return IPC_FAIL(this, "RecvPostMessages not entangled");
55 // This converts the object in a data struct where we have BlobImpls.
56 FallibleTArray<RefPtr<SharedMessageBody>> messages;
57 if (NS_WARN_IF(!SharedMessageBody::FromMessagesToSharedParent(aMessages,
58 messages))) {
59 // FromMessagesToSharedParent() returns false only if the array allocation
60 // failed.
61 // See bug 1750497 for further discussion if this is the wanted behavior.
62 return IPC_FAIL(this, "SharedMessageBody::FromMessagesToSharedParent");
65 if (messages.IsEmpty()) {
66 // An empty payload can be safely ignored.
67 return IPC_OK();
70 if (!mService->PostMessages(this, std::move(messages))) {
71 // TODO: Verify if all failure conditions of PostMessages() merit an
72 // IPC_FAIL. See bug 1750499.
73 return IPC_FAIL(this, "RecvPostMessages->PostMessages");
75 return IPC_OK();
78 mozilla::ipc::IPCResult MessagePortParent::RecvDisentangle(
79 nsTArray<MessageData>&& aMessages) {
80 if (!mService) {
81 NS_WARNING("Entangle is called after a shutdown!");
82 // This implies most probably that CloseAndDelete() has been already called
83 // such that we can silently ignore this call.
84 return IPC_OK();
87 if (!mEntangled) {
88 // If we were shut down, the above condition already bailed out. So this
89 // should actually never happen and returning a failure is fine.
90 return IPC_FAIL(this, "RecvDisentangle not entangled");
93 // This converts the object in a data struct where we have BlobImpls.
94 FallibleTArray<RefPtr<SharedMessageBody>> messages;
95 if (NS_WARN_IF(!SharedMessageBody::FromMessagesToSharedParent(aMessages,
96 messages))) {
97 // TODO: Verify if failed allocations merit an IPC_FAIL. See bug 1750497.
98 return IPC_FAIL(this, "SharedMessageBody::FromMessagesToSharedParent");
101 if (!mService->DisentanglePort(this, std::move(messages))) {
102 // TODO: Verify if all failure conditions of DisentanglePort() merit an
103 // IPC_FAIL. See bug 1750501.
104 return IPC_FAIL(this, "RecvDisentangle->DisentanglePort");
107 CloseAndDelete();
108 return IPC_OK();
111 mozilla::ipc::IPCResult MessagePortParent::RecvStopSendingData() {
112 if (!mEntangled) {
113 return IPC_OK();
116 mCanSendData = false;
117 Unused << SendStopSendingDataConfirmed();
118 return IPC_OK();
121 mozilla::ipc::IPCResult MessagePortParent::RecvClose() {
122 if (mService) {
123 MOZ_ASSERT(mEntangled);
125 if (!mService->ClosePort(this)) {
126 return IPC_FAIL(this, "RecvClose->ClosePort");
129 Close();
132 MOZ_ASSERT(!mEntangled);
134 Unused << Send__delete__(this);
135 return IPC_OK();
138 void MessagePortParent::ActorDestroy(ActorDestroyReason aWhy) {
139 if (mService && mEntangled) {
140 // When the last parent is deleted, this service is freed but this cannot
141 // be done when the hashtables are written by CloseAll.
142 RefPtr<MessagePortService> kungFuDeathGrip = mService;
143 kungFuDeathGrip->ParentDestroy(this);
147 bool MessagePortParent::Entangled(nsTArray<MessageData>&& aMessages) {
148 MOZ_ASSERT(!mEntangled);
149 mEntangled = true;
150 return SendEntangled(aMessages);
153 void MessagePortParent::CloseAndDelete() {
154 Close();
155 Unused << Send__delete__(this);
158 void MessagePortParent::Close() {
159 mService = nullptr;
160 mEntangled = false;
163 /* static */
164 bool MessagePortParent::ForceClose(const nsID& aUUID,
165 const nsID& aDestinationUUID,
166 const uint32_t& aSequenceID) {
167 MessagePortService* service = MessagePortService::Get();
168 if (!service) {
169 NS_WARNING(
170 "The service must exist if we want to close an existing MessagePort.");
171 // There is nothing to close so we are ok.
172 return true;
175 return service->ForceClose(aUUID, aDestinationUUID, aSequenceID);
178 } // namespace mozilla::dom