OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ipc_sync_channel.h" | 5 #include "ipc/ipc_sync_channel.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/location.h" | 10 #include "base/location.h" |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 return base::Bind(&SyncChannel::SyncContext::OnWaitableEventSignaled, this); | 404 return base::Bind(&SyncChannel::SyncContext::OnWaitableEventSignaled, this); |
405 } | 405 } |
406 | 406 |
407 SyncChannel::SyncChannel( | 407 SyncChannel::SyncChannel( |
408 const IPC::ChannelHandle& channel_handle, | 408 const IPC::ChannelHandle& channel_handle, |
409 Channel::Mode mode, | 409 Channel::Mode mode, |
410 Listener* listener, | 410 Listener* listener, |
411 base::SingleThreadTaskRunner* ipc_task_runner, | 411 base::SingleThreadTaskRunner* ipc_task_runner, |
412 bool create_pipe_now, | 412 bool create_pipe_now, |
413 WaitableEvent* shutdown_event) | 413 WaitableEvent* shutdown_event) |
414 : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)), | 414 : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)) { |
415 sync_messages_with_no_timeout_allowed_(true) { | |
416 ChannelProxy::Init(channel_handle, mode, create_pipe_now); | 415 ChannelProxy::Init(channel_handle, mode, create_pipe_now); |
417 StartWatching(); | 416 StartWatching(); |
418 } | 417 } |
419 | 418 |
420 SyncChannel::SyncChannel( | 419 SyncChannel::SyncChannel( |
421 Listener* listener, | 420 Listener* listener, |
422 base::SingleThreadTaskRunner* ipc_task_runner, | 421 base::SingleThreadTaskRunner* ipc_task_runner, |
423 WaitableEvent* shutdown_event) | 422 WaitableEvent* shutdown_event) |
424 : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)), | 423 : ChannelProxy(new SyncContext(listener, ipc_task_runner, shutdown_event)) { |
425 sync_messages_with_no_timeout_allowed_(true) { | |
426 StartWatching(); | 424 StartWatching(); |
427 } | 425 } |
428 | 426 |
429 SyncChannel::~SyncChannel() { | 427 SyncChannel::~SyncChannel() { |
430 } | 428 } |
431 | 429 |
432 void SyncChannel::SetRestrictDispatchChannelGroup(int group) { | 430 void SyncChannel::SetRestrictDispatchChannelGroup(int group) { |
433 sync_context()->set_restrict_dispatch_group(group); | 431 sync_context()->set_restrict_dispatch_group(group); |
434 } | 432 } |
435 | 433 |
436 bool SyncChannel::Send(Message* message) { | 434 bool SyncChannel::Send(Message* message) { |
437 return SendWithTimeout(message, base::kNoTimeout); | |
438 } | |
439 | |
440 bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) { | |
441 #ifdef IPC_MESSAGE_LOG_ENABLED | 435 #ifdef IPC_MESSAGE_LOG_ENABLED |
442 Logging* logger = Logging::GetInstance(); | 436 Logging* logger = Logging::GetInstance(); |
443 std::string name; | 437 std::string name; |
444 logger->GetMessageText(message->type(), &name, message, NULL); | 438 logger->GetMessageText(message->type(), &name, message, NULL); |
445 TRACE_EVENT1("toplevel", "SyncChannel::SendWithTimeout", | 439 TRACE_EVENT1("toplevel", "SyncChannel::Send", "name", name); |
446 "name", name); | |
447 #else | 440 #else |
448 TRACE_EVENT2("toplevel", "SyncChannel::SendWithTimeout", | 441 TRACE_EVENT2("toplevel", "SyncChannel::Send", |
449 "class", IPC_MESSAGE_ID_CLASS(message->type()), | 442 "class", IPC_MESSAGE_ID_CLASS(message->type()), |
450 "line", IPC_MESSAGE_ID_LINE(message->type())); | 443 "line", IPC_MESSAGE_ID_LINE(message->type())); |
451 #endif | 444 #endif |
452 if (!message->is_sync()) { | 445 if (!message->is_sync()) { |
453 ChannelProxy::Send(message); | 446 ChannelProxy::Send(message); |
454 return true; | 447 return true; |
455 } | 448 } |
456 | 449 |
457 // *this* might get deleted in WaitForReply. | 450 // *this* might get deleted in WaitForReply. |
458 scoped_refptr<SyncContext> context(sync_context()); | 451 scoped_refptr<SyncContext> context(sync_context()); |
459 if (context->shutdown_event()->IsSignaled()) { | 452 if (context->shutdown_event()->IsSignaled()) { |
460 VLOG(1) << "shutdown event is signaled"; | 453 VLOG(1) << "shutdown event is signaled"; |
461 delete message; | 454 delete message; |
462 return false; | 455 return false; |
463 } | 456 } |
464 | 457 |
465 DCHECK(sync_messages_with_no_timeout_allowed_ || | |
466 timeout_ms != base::kNoTimeout); | |
467 SyncMessage* sync_msg = static_cast<SyncMessage*>(message); | 458 SyncMessage* sync_msg = static_cast<SyncMessage*>(message); |
468 context->Push(sync_msg); | 459 context->Push(sync_msg); |
469 int message_id = SyncMessage::GetMessageId(*sync_msg); | |
470 WaitableEvent* pump_messages_event = sync_msg->pump_messages_event(); | 460 WaitableEvent* pump_messages_event = sync_msg->pump_messages_event(); |
471 | 461 |
472 ChannelProxy::Send(message); | 462 ChannelProxy::Send(message); |
473 | 463 |
474 if (timeout_ms != base::kNoTimeout) { | |
475 // We use the sync message id so that when a message times out, we don't | |
476 // confuse it with another send that is either above/below this Send in | |
477 // the call stack. | |
478 context->ipc_task_runner()->PostDelayedTask( | |
479 FROM_HERE, | |
480 base::Bind(&SyncContext::OnSendTimeout, context.get(), message_id), | |
481 base::TimeDelta::FromMilliseconds(timeout_ms)); | |
482 } | |
483 | |
484 // Wait for reply, or for any other incoming synchronous messages. | 464 // Wait for reply, or for any other incoming synchronous messages. |
485 // *this* might get deleted, so only call static functions at this point. | 465 // *this* might get deleted, so only call static functions at this point. |
486 WaitForReply(context.get(), pump_messages_event); | 466 WaitForReply(context.get(), pump_messages_event); |
487 | 467 |
488 return context->Pop(); | 468 return context->Pop(); |
489 } | 469 } |
490 | 470 |
491 void SyncChannel::WaitForReply( | 471 void SyncChannel::WaitForReply( |
492 SyncContext* context, WaitableEvent* pump_messages_event) { | 472 SyncContext* context, WaitableEvent* pump_messages_event) { |
493 context->DispatchMessages(); | 473 context->DispatchMessages(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 // manual reset since the object watcher might otherwise reset the event | 550 // manual reset since the object watcher might otherwise reset the event |
571 // when we're doing a WaitMany. | 551 // when we're doing a WaitMany. |
572 dispatch_watcher_callback_ = | 552 dispatch_watcher_callback_ = |
573 base::Bind(&SyncChannel::OnWaitableEventSignaled, | 553 base::Bind(&SyncChannel::OnWaitableEventSignaled, |
574 base::Unretained(this)); | 554 base::Unretained(this)); |
575 dispatch_watcher_.StartWatching(sync_context()->GetDispatchEvent(), | 555 dispatch_watcher_.StartWatching(sync_context()->GetDispatchEvent(), |
576 dispatch_watcher_callback_); | 556 dispatch_watcher_callback_); |
577 } | 557 } |
578 | 558 |
579 } // namespace IPC | 559 } // namespace IPC |
OLD | NEW |