summaryrefslogtreecommitdiffstats
path: root/ipc/ipc_sync_channel.cc
diff options
context:
space:
mode:
authorjhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-11 22:39:54 +0000
committerjhorwich@chromium.org <jhorwich@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-11 22:39:54 +0000
commit522cc10d714c4a2e519176a8f24d2549820f63dc (patch)
tree1860802c1776ec2669811866f9be16f0cfd1275e /ipc/ipc_sync_channel.cc
parent76b2482e4bb8586807d92025b942817030b3690d (diff)
downloadchromium_src-522cc10d714c4a2e519176a8f24d2549820f63dc.zip
chromium_src-522cc10d714c4a2e519176a8f24d2549820f63dc.tar.gz
chromium_src-522cc10d714c4a2e519176a8f24d2549820f63dc.tar.bz2
Reimplement ReceivedSyncMsgQueue::DispatchMessages
Implementation of IPC::SyncChannel::ReceivedSyncMsgQueue::DispatchMessages that does not hold any messages in a local stack-frame's delayed_queue, which was causing me to see an inbound sync message from a plugin not dispatched while the renderer was waiting for replies from the plugin. This was causing the plugin and renderer to deadlock waiting for each other. BUG=108491 TEST=Run Pepperized O3D and observe for tab hangs TEST=Run ipc_tests unittests Review URL: http://codereview.chromium.org/9022038 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117309 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/ipc_sync_channel.cc')
-rw-r--r--ipc/ipc_sync_channel.cc46
1 files changed, 29 insertions, 17 deletions
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index f3c5384..74d9744 100644
--- a/ipc/ipc_sync_channel.cc
+++ b/ipc/ipc_sync_channel.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -64,6 +64,7 @@ class SyncChannel::ReceivedSyncMsgQueue :
// We set the event in case the listener thread is blocked (or is about
// to). In case it's not, the PostTask dispatches the messages.
message_queue_.push_back(QueuedMessage(new Message(msg), context));
+ message_queue_version_++;
}
dispatch_event_.Signal();
@@ -89,27 +90,35 @@ class SyncChannel::ReceivedSyncMsgQueue :
}
void DispatchMessages(SyncContext* dispatching_context) {
- SyncMessageQueue delayed_queue;
+ bool first_time = true;
+ uint32 expected_version = 0;
+ SyncMessageQueue::iterator it;
while (true) {
- Message* message;
+ Message* message = NULL;
scoped_refptr<SyncChannel::SyncContext> context;
{
base::AutoLock auto_lock(message_lock_);
- if (message_queue_.empty()) {
- message_queue_ = delayed_queue;
- break;
+ if (first_time || message_queue_version_ != expected_version) {
+ it = message_queue_.begin();
+ first_time = false;
+ }
+ for (; it != message_queue_.end(); it++) {
+ if (!it->context->restrict_dispatch() ||
+ it->context == dispatching_context) {
+ message = it->message;
+ context = it->context;
+ it = message_queue_.erase(it);
+ message_queue_version_++;
+ expected_version = message_queue_version_;
+ break;
+ }
}
-
- message = message_queue_.front().message;
- context = message_queue_.front().context;
- message_queue_.pop_front();
- }
- if (context->restrict_dispatch() && context != dispatching_context) {
- delayed_queue.push_back(QueuedMessage(message, context));
- } else {
- context->OnDispatchMessage(*message);
- delete message;
}
+
+ if (message == NULL)
+ break;
+ context->OnDispatchMessage(*message);
+ delete message;
}
}
@@ -122,6 +131,7 @@ class SyncChannel::ReceivedSyncMsgQueue :
if (iter->context == context) {
delete iter->message;
iter = message_queue_.erase(iter);
+ message_queue_version_++;
} else {
iter++;
}
@@ -169,6 +179,7 @@ class SyncChannel::ReceivedSyncMsgQueue :
// See the comment in SyncChannel::SyncChannel for why this event is created
// as manual reset.
ReceivedSyncMsgQueue() :
+ message_queue_version_(0),
dispatch_event_(true, false),
listener_message_loop_(base::MessageLoopProxy::current()),
task_pending_(false),
@@ -185,8 +196,9 @@ class SyncChannel::ReceivedSyncMsgQueue :
scoped_refptr<SyncChannel::SyncContext> context;
};
- typedef std::deque<QueuedMessage> SyncMessageQueue;
+ typedef std::list<QueuedMessage> SyncMessageQueue;
SyncMessageQueue message_queue_;
+ uint32 message_queue_version_; // Used to signal DispatchMessages to rescan
std::vector<QueuedMessage> received_replies_;