Source code

Revision control

Other Tools

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 "MessagePortParent.h"
8
#include "MessagePortService.h"
9
#include "SharedMessagePortMessage.h"
10
#include "mozilla/Unused.h"
11
12
namespace mozilla {
13
namespace dom {
14
15
MessagePortParent::MessagePortParent(const nsID& aUUID)
16
: mService(MessagePortService::GetOrCreate()),
17
mUUID(aUUID),
18
mEntangled(false),
19
mCanSendData(true) {
20
MOZ_ASSERT(mService);
21
}
22
23
MessagePortParent::~MessagePortParent() {
24
MOZ_ASSERT(!mService);
25
MOZ_ASSERT(!mEntangled);
26
}
27
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;
33
}
34
35
MOZ_ASSERT(!mEntangled);
36
37
return mService->RequestEntangling(this, aDestinationUUID, aSequenceID);
38
}
39
40
mozilla::ipc::IPCResult MessagePortParent::RecvPostMessages(
41
nsTArray<ClonedMessageData>&& aMessages) {
42
// This converts the object in a data struct where we have BlobImpls.
43
FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
44
if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent(
45
aMessages, messages))) {
46
return IPC_FAIL_NO_REASON(this);
47
}
48
49
if (!mEntangled) {
50
return IPC_FAIL_NO_REASON(this);
51
}
52
53
if (!mService) {
54
NS_WARNING("Entangle is called after a shutdown!");
55
return IPC_FAIL_NO_REASON(this);
56
}
57
58
if (messages.IsEmpty()) {
59
return IPC_FAIL_NO_REASON(this);
60
}
61
62
if (!mService->PostMessages(this, messages)) {
63
return IPC_FAIL_NO_REASON(this);
64
}
65
return IPC_OK();
66
}
67
68
mozilla::ipc::IPCResult MessagePortParent::RecvDisentangle(
69
nsTArray<ClonedMessageData>&& aMessages) {
70
// This converts the object in a data struct where we have BlobImpls.
71
FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
72
if (NS_WARN_IF(!SharedMessagePortMessage::FromMessagesToSharedParent(
73
aMessages, messages))) {
74
return IPC_FAIL_NO_REASON(this);
75
}
76
77
if (!mEntangled) {
78
return IPC_FAIL_NO_REASON(this);
79
}
80
81
if (!mService) {
82
NS_WARNING("Entangle is called after a shutdown!");
83
return IPC_FAIL_NO_REASON(this);
84
}
85
86
if (!mService->DisentanglePort(this, messages)) {
87
return IPC_FAIL_NO_REASON(this);
88
}
89
90
CloseAndDelete();
91
return IPC_OK();
92
}
93
94
mozilla::ipc::IPCResult MessagePortParent::RecvStopSendingData() {
95
if (!mEntangled) {
96
return IPC_OK();
97
}
98
99
mCanSendData = false;
100
Unused << SendStopSendingDataConfirmed();
101
return IPC_OK();
102
}
103
104
mozilla::ipc::IPCResult MessagePortParent::RecvClose() {
105
if (mService) {
106
MOZ_ASSERT(mEntangled);
107
108
if (!mService->ClosePort(this)) {
109
return IPC_FAIL_NO_REASON(this);
110
}
111
112
Close();
113
}
114
115
MOZ_ASSERT(!mEntangled);
116
117
Unused << Send__delete__(this);
118
return IPC_OK();
119
}
120
121
void MessagePortParent::ActorDestroy(ActorDestroyReason aWhy) {
122
if (mService && mEntangled) {
123
// When the last parent is deleted, this service is freed but this cannot
124
// be done when the hashtables are written by CloseAll.
125
RefPtr<MessagePortService> kungFuDeathGrip = mService;
126
kungFuDeathGrip->ParentDestroy(this);
127
}
128
}
129
130
bool MessagePortParent::Entangled(
131
const nsTArray<ClonedMessageData>& aMessages) {
132
MOZ_ASSERT(!mEntangled);
133
mEntangled = true;
134
return SendEntangled(aMessages);
135
}
136
137
void MessagePortParent::CloseAndDelete() {
138
Close();
139
Unused << Send__delete__(this);
140
}
141
142
void MessagePortParent::Close() {
143
mService = nullptr;
144
mEntangled = false;
145
}
146
147
/* static */
148
bool MessagePortParent::ForceClose(const nsID& aUUID,
149
const nsID& aDestinationUUID,
150
const uint32_t& aSequenceID) {
151
MessagePortService* service = MessagePortService::Get();
152
if (!service) {
153
NS_WARNING(
154
"The service must exist if we want to close an existing MessagePort.");
155
return false;
156
}
157
158
return service->ForceClose(aUUID, aDestinationUUID, aSequenceID);
159
}
160
161
} // namespace dom
162
} // namespace mozilla