Coverage Report

Created: 2018-09-25 14:53

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