| Index: ipc/ipc_sync_channel.cc
|
| diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
|
| index 1c7edfa6d59521c55685327854c510835b145712..3dcab2c2db921d2809b982f13b67f3cc02b1ac43 100644
|
| --- a/ipc/ipc_sync_channel.cc
|
| +++ b/ipc/ipc_sync_channel.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| +// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -68,7 +68,9 @@ class SyncChannel::ReceivedSyncMsgQueue :
|
| dispatch_event_.Signal();
|
| if (!was_task_pending) {
|
| listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(
|
| - this, &ReceivedSyncMsgQueue::DispatchMessagesTask));
|
| + this,
|
| + &ReceivedSyncMsgQueue::DispatchMessagesTask,
|
| + scoped_refptr<SyncContext>(context)));
|
| }
|
| }
|
|
|
| @@ -78,30 +80,36 @@ class SyncChannel::ReceivedSyncMsgQueue :
|
|
|
| // Called on the listener's thread to process any queues synchronous
|
| // messages.
|
| - void DispatchMessagesTask() {
|
| + void DispatchMessagesTask(SyncContext* context) {
|
| {
|
| base::AutoLock auto_lock(message_lock_);
|
| task_pending_ = false;
|
| }
|
| - DispatchMessages();
|
| + context->DispatchMessages();
|
| }
|
|
|
| - void DispatchMessages() {
|
| + void DispatchMessages(SyncContext* dispatching_context) {
|
| + SyncMessageQueue delayed_queue;
|
| while (true) {
|
| Message* message;
|
| scoped_refptr<SyncChannel::SyncContext> context;
|
| {
|
| base::AutoLock auto_lock(message_lock_);
|
| - if (message_queue_.empty())
|
| + if (message_queue_.empty()) {
|
| + message_queue_ = delayed_queue;
|
| break;
|
| + }
|
|
|
| message = message_queue_.front().message;
|
| context = message_queue_.front().context;
|
| message_queue_.pop_front();
|
| }
|
| -
|
| - context->OnDispatchMessage(*message);
|
| - delete message;
|
| + if (context->restrict_dispatch() && context != dispatching_context) {
|
| + delayed_queue.push_back(QueuedMessage(message, context));
|
| + } else {
|
| + context->OnDispatchMessage(*message);
|
| + delete message;
|
| + }
|
| }
|
| }
|
|
|
| @@ -204,7 +212,8 @@ SyncChannel::SyncContext::SyncContext(
|
| WaitableEvent* shutdown_event)
|
| : ChannelProxy::Context(listener, ipc_thread),
|
| received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()),
|
| - shutdown_event_(shutdown_event) {
|
| + shutdown_event_(shutdown_event),
|
| + restrict_dispatch_(false) {
|
| }
|
|
|
| SyncChannel::SyncContext::~SyncContext() {
|
| @@ -260,7 +269,7 @@ WaitableEvent* SyncChannel::SyncContext::GetDispatchEvent() {
|
| }
|
|
|
| void SyncChannel::SyncContext::DispatchMessages() {
|
| - received_sync_msgs_->DispatchMessages();
|
| + received_sync_msgs_->DispatchMessages(this);
|
| }
|
|
|
| bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) {
|
| @@ -378,6 +387,10 @@ SyncChannel::SyncChannel(
|
| SyncChannel::~SyncChannel() {
|
| }
|
|
|
| +void SyncChannel::SetRestrictDispatchToSameChannel(bool value) {
|
| + sync_context()->set_restrict_dispatch(value);
|
| +}
|
| +
|
| bool SyncChannel::Send(Message* message) {
|
| return SendWithTimeout(message, base::kNoTimeout);
|
| }
|
| @@ -422,6 +435,7 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) {
|
|
|
| void SyncChannel::WaitForReply(
|
| SyncContext* context, WaitableEvent* pump_messages_event) {
|
| + context->DispatchMessages();
|
| while (true) {
|
| WaitableEvent* objects[] = {
|
| context->GetDispatchEvent(),
|
|
|