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

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

Issue 2750373002: Revert of Mojo: Armed Watchers (Closed)
Patch Set: Created 3 years, 9 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') | ios/web/webui/mojo_facade.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/message_port.h" 5 #include "content/common/message_port.h"
6 6
7 #include "base/bind.h"
8 #include "base/logging.h" 7 #include "base/logging.h"
9 #include "base/threading/thread_task_runner_handle.h"
10 8
11 namespace content { 9 namespace content {
12 10
13 MessagePort::~MessagePort() { 11 MessagePort::~MessagePort() {
14 } 12 }
15 13
16 MessagePort::MessagePort() : state_(new State()) { 14 MessagePort::MessagePort() : state_(new State()) {
17 } 15 }
18 16
19 MessagePort::MessagePort(const MessagePort& other) : state_(other.state_) { 17 MessagePort::MessagePort(const MessagePort& other) : state_(other.state_) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 } 140 }
143 141
144 MessagePort::State::State(mojo::ScopedMessagePipeHandle handle) 142 MessagePort::State::State(mojo::ScopedMessagePipeHandle handle)
145 : handle_(std::move(handle)) { 143 : handle_(std::move(handle)) {
146 } 144 }
147 145
148 void MessagePort::State::AddWatch() { 146 void MessagePort::State::AddWatch() {
149 if (!callback_) 147 if (!callback_)
150 return; 148 return;
151 149
152 DCHECK(!watcher_handle_.is_valid());
153 MojoResult rv = CreateWatcher(&State::CallOnHandleReady, &watcher_handle_);
154 DCHECK_EQ(MOJO_RESULT_OK, rv);
155
156 // We use a scoped_refptr<State> instance as the watch context. This is owned
157 // by the watch and deleted upon receiving a cancellation notification.
158 scoped_refptr<State>* state_ref = new scoped_refptr<State>(this);
159 context_ = reinterpret_cast<uintptr_t>(state_ref);
160
161 // NOTE: An HTML MessagePort does not receive an event to tell it when the 150 // NOTE: An HTML MessagePort does not receive an event to tell it when the
162 // peer has gone away, so we only watch for readability here. 151 // peer has gone away, so we only watch for readability here.
163 rv = MojoWatch(watcher_handle_.get().value(), handle_.get().value(), 152 MojoResult rv = MojoWatch(handle_.get().value(),
164 MOJO_HANDLE_SIGNAL_READABLE, context_); 153 MOJO_HANDLE_SIGNAL_READABLE,
165 DCHECK_EQ(MOJO_RESULT_OK, rv); 154 &MessagePort::State::OnHandleReady,
166 155 reinterpret_cast<uintptr_t>(this));
167 ArmWatcher(); 156 if (rv != MOJO_RESULT_OK)
157 DVLOG(1) << this << " MojoWatch failed: " << rv;
168 } 158 }
169 159
170 void MessagePort::State::CancelWatch() { 160 void MessagePort::State::CancelWatch() {
171 watcher_handle_.reset(); 161 if (!callback_)
172 context_ = 0; 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));
173 } 167 }
174 168
175 MessagePort::State::~State() = default; 169 // static
176 170 void MessagePort::State::OnHandleReady(
177 void MessagePort::State::ArmWatcher() { 171 uintptr_t context,
178 if (!watcher_handle_.is_valid()) 172 MojoResult result,
179 return; 173 MojoHandleSignalsState signals_state,
180 174 MojoWatchNotificationFlags flags) {
181 uint32_t num_ready_contexts = 1; 175 if (result == MOJO_RESULT_OK) {
182 uintptr_t ready_context; 176 reinterpret_cast<MessagePort::State*>(context)->callback_.Run();
183 MojoResult ready_result;
184 MojoHandleSignalsState ready_state;
185 MojoResult rv =
186 MojoArmWatcher(watcher_handle_.get().value(), &num_ready_contexts,
187 &ready_context, &ready_result, &ready_state);
188 if (rv == MOJO_RESULT_OK)
189 return;
190
191 // The watcher could not be armed because it would notify immediately.
192 DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv);
193 DCHECK_EQ(1u, num_ready_contexts);
194 DCHECK_EQ(context_, ready_context);
195
196 if (ready_result == MOJO_RESULT_OK) {
197 // The handle is already signaled, so we trigger a callback now.
198 base::ThreadTaskRunnerHandle::Get()->PostTask(
199 FROM_HERE, base::Bind(&State::OnHandleReady, this, MOJO_RESULT_OK));
200 return;
201 }
202
203 if (ready_result == MOJO_RESULT_FAILED_PRECONDITION) {
204 DVLOG(1) << this << " MojoArmWatcher failed because of a broken pipe.";
205 return;
206 }
207
208 NOTREACHED();
209 }
210
211 void MessagePort::State::OnHandleReady(MojoResult result) {
212 if (result == MOJO_RESULT_OK && callback_) {
213 callback_.Run();
214 ArmWatcher();
215 } else { 177 } else {
216 // And now his watch is ended. 178 // And now his watch is ended.
217 } 179 }
218 } 180 }
219 181
220 // static 182 MessagePort::State::~State() {
221 void MessagePort::State::CallOnHandleReady(uintptr_t context, 183 CancelWatch();
222 MojoResult result,
223 MojoHandleSignalsState signals_state,
224 MojoWatcherNotificationFlags flags) {
225 auto* state_ref = reinterpret_cast<scoped_refptr<State>*>(context);
226 if (result == MOJO_RESULT_CANCELLED) {
227 // Last notification. Delete the watch's owned State ref.
228 delete state_ref;
229 } else {
230 (*state_ref)->OnHandleReady(result);
231 }
232 } 184 }
233 185
234 } // namespace content 186 } // namespace content
OLDNEW
« no previous file with comments | « content/common/message_port.h ('k') | ios/web/webui/mojo_facade.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698