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

Side by Side Diff: ipc/mojo/ipc_channel_mojo.cc

Issue 780223002: ChannelProxy: Send() from UI thread when ChannelMojo is used. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years 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 | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_message_pipe_reader.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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "ipc/mojo/ipc_channel_mojo.h" 5 #include "ipc/mojo/ipc_channel_mojo.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "ipc/ipc_listener.h" 10 #include "ipc/ipc_listener.h"
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 void ChannelMojo::ChannelInfoDeleter::operator()( 168 void ChannelMojo::ChannelInfoDeleter::operator()(
169 mojo::embedder::ChannelInfo* ptr) const { 169 mojo::embedder::ChannelInfo* ptr) const {
170 mojo::embedder::DestroyChannel(ptr); 170 mojo::embedder::DestroyChannel(ptr);
171 } 171 }
172 172
173 //------------------------------------------------------------------------------ 173 //------------------------------------------------------------------------------
174 174
175 // static 175 // static
176 bool ChannelMojo::ShouldBeUsed() { 176 bool ChannelMojo::ShouldBeUsed() {
177 // TODO(morrita): Turn this on for a set of platforms. 177 // TODO(morrita): Turn this on for a set of platforms.
178 return false; 178 return true;
Hajime Morrita 2014/12/05 02:54:09 I do this just for exercising tests. No intention
179 } 179 }
180 180
181 // static 181 // static
182 scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate, 182 scoped_ptr<ChannelMojo> ChannelMojo::Create(ChannelMojo::Delegate* delegate,
183 const ChannelHandle& channel_handle, 183 const ChannelHandle& channel_handle,
184 Mode mode, 184 Mode mode,
185 Listener* listener) { 185 Listener* listener) {
186 switch (mode) { 186 switch (mode) {
187 case Channel::MODE_CLIENT: 187 case Channel::MODE_CLIENT:
188 return make_scoped_ptr( 188 return make_scoped_ptr(
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 &ChannelMojo::InitDelegate, base::Unretained(this), delegate)); 233 &ChannelMojo::InitDelegate, base::Unretained(this), delegate));
234 } 234 }
235 } 235 }
236 } 236 }
237 237
238 ChannelMojo::~ChannelMojo() { 238 ChannelMojo::~ChannelMojo() {
239 Close(); 239 Close();
240 } 240 }
241 241
242 void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) { 242 void ChannelMojo::InitDelegate(ChannelMojo::Delegate* delegate) {
243 delegate->OnChannelCreated(weak_factory_.GetWeakPtr());
244 base::AutoLock l(lock_);
243 delegate_ = delegate->ToWeakPtr(); 245 delegate_ = delegate->ToWeakPtr();
244 delegate_->OnChannelCreated(weak_factory_.GetWeakPtr());
245 } 246 }
246 247
247 mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe( 248 mojo::ScopedMessagePipeHandle ChannelMojo::CreateMessagingPipe(
248 mojo::embedder::ScopedPlatformHandle handle) { 249 mojo::embedder::ScopedPlatformHandle handle) {
249 DCHECK(!channel_info_.get()); 250 DCHECK(!channel_info_.get());
250 mojo::embedder::ChannelInfo* channel_info; 251 mojo::embedder::ChannelInfo* channel_info;
251 mojo::ScopedMessagePipeHandle pipe = 252 mojo::ScopedMessagePipeHandle pipe =
252 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info); 253 mojo::embedder::CreateChannelOnIOThread(handle.Pass(), &channel_info);
253 channel_info_.reset(channel_info); 254 channel_info_.reset(channel_info);
254 return pipe.Pass(); 255 return pipe.Pass();
255 } 256 }
256 257
257 bool ChannelMojo::Connect() { 258 bool ChannelMojo::Connect() {
258 DCHECK(!message_reader_); 259 DCHECK(!message_reader_);
259 return bootstrap_->Connect(); 260 return bootstrap_->Connect();
260 } 261 }
261 262
262 void ChannelMojo::Close() { 263 void ChannelMojo::Close() {
263 message_reader_.reset(); 264 // |message_reader_| has to be cleared inside the lock,
265 // but the instance has to be deleted outside.
266 scoped_ptr<internal::MessagePipeReader, ReaderDeleter> to_be_dead;
267
268 base::AutoLock l(lock_);
269 to_be_dead = message_reader_.Pass();
264 channel_info_.reset(); 270 channel_info_.reset();
265 } 271 }
266 272
267 void ChannelMojo::OnBootstrapError() { 273 void ChannelMojo::OnBootstrapError() {
268 listener_->OnChannelError(); 274 listener_->OnChannelError();
269 } 275 }
270 276
271 void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe, 277 void ChannelMojo::InitMessageReader(mojo::ScopedMessagePipeHandle pipe,
272 int32_t peer_pid) { 278 int32_t peer_pid) {
273 message_reader_ = 279 scoped_ptr<internal::MessagePipeReader> reader =
274 make_scoped_ptr(new internal::MessagePipeReader(pipe.Pass(), this)); 280 make_scoped_ptr(new internal::MessagePipeReader(pipe.Pass(), this));
281 MojoResult send_result = MOJO_RESULT_OK;
275 282
276 for (size_t i = 0; i < pending_messages_.size(); ++i) { 283 {
277 bool sent = message_reader_->Send(make_scoped_ptr(pending_messages_[i])); 284 base::AutoLock l(lock_);
278 pending_messages_[i] = NULL; 285 ScopedVector<Message> pending;
279 if (!sent) { 286
280 pending_messages_.clear(); 287 pending_messages_.swap(pending);
281 listener_->OnChannelError(); 288 for (size_t i = 0; i < pending.size(); ++i) {
282 return; 289 send_result = reader->Send(make_scoped_ptr(pending[i]));
290 pending[i] = nullptr;
291 if (send_result != MOJO_RESULT_OK)
292 break;
283 } 293 }
294
295 // We set |message_reader_| here and won't get any |pending_messages_|
296 // hereafter. Although we might have some if there is an error, we don't
297 // care. They cannot be sent anyway.
298 if (send_result == MOJO_RESULT_OK)
299 message_reader_ = reader.Pass();
284 } 300 }
285 301
286 pending_messages_.clear(); 302 // This should be done outside the |lock_| as delegates are called through
303 // |CloseWithError()|.
304 if (reader.get()) {
305 DCHECK(!message_reader_.get());
306 reader->CloseWithError(send_result);
307 return;
308 }
287 309
310 DCHECK(message_reader_.get());
288 set_peer_pid(peer_pid); 311 set_peer_pid(peer_pid);
289 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID())); 312 listener_->OnChannelConnected(static_cast<int32_t>(GetPeerPID()));
290 } 313 }
291 314
292 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) { 315 void ChannelMojo::OnPipeClosed(internal::MessagePipeReader* reader) {
293 Close(); 316 Close();
294 } 317 }
295 318
296 void ChannelMojo::OnPipeError(internal::MessagePipeReader* reader) { 319 void ChannelMojo::OnPipeError(internal::MessagePipeReader* reader) {
297 listener_->OnChannelError(); 320 listener_->OnChannelError();
298 } 321 }
299 322
323 base::TaskRunner* ChannelMojo::GetIOTaskRunner() {
324 base::AutoLock l(lock_);
325 if (!delegate_)
326 return nullptr;
327 return delegate_->GetIOTaskRunner().get();
328 }
300 329
330 // Reminder: Be thread-safe.
301 bool ChannelMojo::Send(Message* message) { 331 bool ChannelMojo::Send(Message* message) {
302 if (!message_reader_) { 332 MojoResult send_result = MOJO_RESULT_OK;
303 pending_messages_.push_back(message); 333
304 return true; 334 {
335 base::AutoLock l(lock_);
336
337 if (!message_reader_) {
338 pending_messages_.push_back(message);
339 return true;
340 }
341
342 send_result = message_reader_->Send(make_scoped_ptr(message));
305 } 343 }
306 344
307 return message_reader_->Send(make_scoped_ptr(message)); 345 if (send_result != MOJO_RESULT_OK) {
346 if (base::TaskRunner* runner = GetIOTaskRunner()) {
347 runner->PostTask(
348 FROM_HERE,
349 base::Bind(&internal::MessagePipeReader::CloseWithError,
350 base::Unretained(message_reader_.get()), send_result));
351 // The error shouln't be visible at this point.
352 // It will be known eventually by |CloseWithError()| on IO thread.
353 return true;
354 }
355
356 message_reader_->CloseWithError(send_result);
357 return false;
358 }
359
360 return true;
361 }
362
363 bool ChannelMojo::IsSendThreadSafe() const {
364 return true;
308 } 365 }
309 366
310 base::ProcessId ChannelMojo::GetPeerPID() const { 367 base::ProcessId ChannelMojo::GetPeerPID() const {
311 return peer_pid_; 368 return peer_pid_;
312 } 369 }
313 370
314 base::ProcessId ChannelMojo::GetSelfPID() const { 371 base::ProcessId ChannelMojo::GetSelfPID() const {
315 return base::GetCurrentProcId(); 372 return base::GetCurrentProcId();
316 } 373 }
317 374
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 449
393 fdset->CommitAll(); 450 fdset->CommitAll();
394 } 451 }
395 452
396 return MOJO_RESULT_OK; 453 return MOJO_RESULT_OK;
397 } 454 }
398 455
399 #endif // defined(OS_POSIX) && !defined(OS_NACL) 456 #endif // defined(OS_POSIX) && !defined(OS_NACL)
400 457
401 } // namespace IPC 458 } // namespace IPC
OLDNEW
« no previous file with comments | « ipc/mojo/ipc_channel_mojo.h ('k') | ipc/mojo/ipc_message_pipe_reader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698