Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: content/public/common/message_port.cc

Issue 2422793002: HTML MessagePort as mojo::MessagePipeHandle (Closed)
Patch Set: Add metrics and support for non-ASCII text messages to Java endpoints Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/public/common/message_port.h"
6
7 #include "base/logging.h"
8
9 namespace content {
10
11 MessagePort::~MessagePort() {
12 }
13
14 MessagePort::MessagePort() : state_(new State()) {
15 }
16
17 MessagePort::MessagePort(const MessagePort& other) : state_(other.state_) {
18 }
19
20 MessagePort& MessagePort::operator=(const MessagePort& other) {
21 state_ = other.state_;
22 return *this;
23 }
24
25 MessagePort::MessagePort(mojo::ScopedMessagePipeHandle handle)
26 : state_(new State(std::move(handle))) {
27 }
28
29 const mojo::ScopedMessagePipeHandle& MessagePort::GetHandle() const {
30 return state_->handle_;
31 }
32
33 mojo::ScopedMessagePipeHandle MessagePort::ReleaseHandle() const {
34 state_->CancelWatch();
35 return std::move(state_->handle_);
36 }
37
38 // static
39 std::vector<mojo::ScopedMessagePipeHandle> MessagePort::ReleaseHandles(
40 const std::vector<MessagePort>& ports) {
41 std::vector<mojo::ScopedMessagePipeHandle> handles(ports.size());
42 for (size_t i = 0; i < ports.size(); ++i)
43 handles[i] = ports[i].ReleaseHandle();
44 return handles;
45 }
46
47 void MessagePort::PostMessage(const base::string16& encoded_message,
48 std::vector<MessagePort> ports) {
49 DCHECK(state_->handle_.is_valid());
50
51 uint32_t num_bytes = encoded_message.size() * sizeof(base::char16);
52
53 // NOTE: It is OK to ignore the return value of MojoWriteMessage here. HTML
54 // MessagePorts have no way of reporting when the peer is gone.
55
56 if (ports.empty()) {
57 MojoWriteMessage(state_->handle_.get().value(),
58 encoded_message.data(),
59 num_bytes,
60 nullptr,
61 0,
62 MOJO_WRITE_MESSAGE_FLAG_NONE);
63 } else {
64 uint32_t num_handles = static_cast<uint32_t>(ports.size());
65 std::unique_ptr<MojoHandle[]> handles(new MojoHandle[num_handles]);
66 for (uint32_t i = 0; i < num_handles; ++i)
67 handles[i] = ports[i].ReleaseHandle().release().value();
68 MojoWriteMessage(state_->handle_.get().value(),
69 encoded_message.data(),
70 num_bytes,
71 handles.get(),
72 num_handles,
73 MOJO_WRITE_MESSAGE_FLAG_NONE);
74 }
75 }
76
77 bool MessagePort::GetMessage(base::string16* encoded_message,
78 std::vector<MessagePort>* ports) {
79 DCHECK(state_->handle_.is_valid());
80
81 uint32_t num_bytes = 0;
82 uint32_t num_handles = 0;
83
84 MojoResult rv = MojoReadMessage(state_->handle_.get().value(),
85 nullptr,
86 &num_bytes,
87 nullptr,
88 &num_handles,
89 MOJO_READ_MESSAGE_FLAG_NONE);
90 if (rv == MOJO_RESULT_OK) {
91 encoded_message->clear();
92 ports->clear();
93 return true;
94 }
95 if (rv != MOJO_RESULT_RESOURCE_EXHAUSTED)
96 return false;
97
98 // XXX ensure num_bytes is a multiple of 2!
jam 2017/01/23 18:08:56 is this an old comment that can be removed?
99 CHECK(num_bytes % 2 == 0);
100
101 base::string16 buffer;
102 buffer.resize(num_bytes / sizeof(base::char16));
103
104 std::unique_ptr<MojoHandle[]> handles;
105 if (num_handles)
106 handles.reset(new MojoHandle[num_handles]);
107
108 rv = MojoReadMessage(state_->handle_.get().value(),
109 num_bytes ? &buffer[0] : nullptr,
110 &num_bytes,
111 handles.get(),
112 &num_handles,
113 MOJO_READ_MESSAGE_FLAG_NONE);
114 if (rv != MOJO_RESULT_OK)
115 return false;
116
117 buffer.swap(*encoded_message);
118
119 if (num_handles) {
120 ports->resize(static_cast<size_t>(num_handles));
121 for (uint32_t i = 0; i < num_handles; ++i) {
122 ports->at(i) = MessagePort(
123 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i])));
124 }
125 }
126 return true;
127 }
128
129 void MessagePort::SetCallback(const base::Closure& callback) {
130 state_->CancelWatch();
131 state_->callback_ = callback;
132 state_->AddWatch();
133 }
134
135 void MessagePort::ClearCallback() {
136 state_->CancelWatch();
137 state_->callback_.Reset();
138 }
139
140 MessagePort::State::State() {
141 }
142
143 MessagePort::State::State(mojo::ScopedMessagePipeHandle handle)
144 : handle_(std::move(handle)) {
145 }
146
147 void MessagePort::State::AddWatch() {
148 if (!callback_)
149 return;
150
151 // NOTE: An HTML MessagePort does not receive an event to tell it when the
152 // peer has gone away, so we only watch for readability here.
153 MojoResult rv = MojoWatch(handle_.get().value(),
154 MOJO_HANDLE_SIGNAL_READABLE,
155 &MessagePort::State::OnHandleReady,
156 reinterpret_cast<uintptr_t>(this));
157 if (rv != MOJO_RESULT_OK)
158 DVLOG(1) << this << " MojoWatch failed: " << rv;
159 }
160
161 void MessagePort::State::CancelWatch() {
162 if (!callback_)
163 return;
164
165 // NOTE: This synchronizes with the thread where OnHandleReady runs so we are
166 // sure to not be racing with it.
167 MojoCancelWatch(handle_.get().value(), reinterpret_cast<uintptr_t>(this));
168 }
169
170 // static
171 void MessagePort::State::OnHandleReady(
172 uintptr_t context,
173 MojoResult result,
174 MojoHandleSignalsState signals_state,
175 MojoWatchNotificationFlags flags) {
176 if (result == MOJO_RESULT_OK) {
177 reinterpret_cast<MessagePort::State*>(context)->callback_.Run();
178 } else {
179 // And now his watch is ended.
180 }
181 }
182
183 MessagePort::State::~State() {
184 CancelWatch();
185 }
186
187 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698