| 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 |