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

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

Issue 2422793002: HTML MessagePort as mojo::MessagePipeHandle (Closed)
Patch Set: Add missing ScopedAsyncTaskScheduler instance for the new unit tests; required by a recent change t… Created 3 years, 10 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
« no previous file with comments | « content/common/message_port.h ('k') | content/common/message_port_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 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/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 CHECK(num_bytes % 2 == 0);
99
100 base::string16 buffer;
101 buffer.resize(num_bytes / sizeof(base::char16));
102
103 std::unique_ptr<MojoHandle[]> handles;
104 if (num_handles)
105 handles.reset(new MojoHandle[num_handles]);
106
107 rv = MojoReadMessage(state_->handle_.get().value(),
108 num_bytes ? &buffer[0] : nullptr,
109 &num_bytes,
110 handles.get(),
111 &num_handles,
112 MOJO_READ_MESSAGE_FLAG_NONE);
113 if (rv != MOJO_RESULT_OK)
114 return false;
115
116 buffer.swap(*encoded_message);
117
118 if (num_handles) {
119 ports->resize(static_cast<size_t>(num_handles));
120 for (uint32_t i = 0; i < num_handles; ++i) {
121 ports->at(i) = MessagePort(
122 mojo::ScopedMessagePipeHandle(mojo::MessagePipeHandle(handles[i])));
123 }
124 }
125 return true;
126 }
127
128 void MessagePort::SetCallback(const base::Closure& callback) {
129 state_->CancelWatch();
130 state_->callback_ = callback;
131 state_->AddWatch();
132 }
133
134 void MessagePort::ClearCallback() {
135 state_->CancelWatch();
136 state_->callback_.Reset();
137 }
138
139 MessagePort::State::State() {
140 }
141
142 MessagePort::State::State(mojo::ScopedMessagePipeHandle handle)
143 : handle_(std::move(handle)) {
144 }
145
146 void MessagePort::State::AddWatch() {
147 if (!callback_)
148 return;
149
150 // NOTE: An HTML MessagePort does not receive an event to tell it when the
151 // peer has gone away, so we only watch for readability here.
152 MojoResult rv = MojoWatch(handle_.get().value(),
153 MOJO_HANDLE_SIGNAL_READABLE,
154 &MessagePort::State::OnHandleReady,
155 reinterpret_cast<uintptr_t>(this));
156 if (rv != MOJO_RESULT_OK)
157 DVLOG(1) << this << " MojoWatch failed: " << rv;
158 }
159
160 void MessagePort::State::CancelWatch() {
161 if (!callback_)
162 return;
163
164 // NOTE: This synchronizes with the thread where OnHandleReady runs so we are
165 // sure to not be racing with it.
166 MojoCancelWatch(handle_.get().value(), reinterpret_cast<uintptr_t>(this));
167 }
168
169 // static
170 void MessagePort::State::OnHandleReady(
171 uintptr_t context,
172 MojoResult result,
173 MojoHandleSignalsState signals_state,
174 MojoWatchNotificationFlags flags) {
175 if (result == MOJO_RESULT_OK) {
176 reinterpret_cast<MessagePort::State*>(context)->callback_.Run();
177 } else {
178 // And now his watch is ended.
179 }
180 }
181
182 MessagePort::State::~State() {
183 CancelWatch();
184 }
185
186 } // namespace content
OLDNEW
« no previous file with comments | « content/common/message_port.h ('k') | content/common/message_port_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698