summaryrefslogtreecommitdiffstats
path: root/ipc/ipc_sync_channel.cc
diff options
context:
space:
mode:
authorpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 03:38:21 +0000
committerpiman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-08 03:38:21 +0000
commit54af05f8ea8050e0ab93dbcc940ac4e1bc4068e5 (patch)
tree3641af4c4223de9f6e742e95b2fc23da4f4ec380 /ipc/ipc_sync_channel.cc
parent5fda613da7a4cb0147bb7d7f9559b541cd45a266 (diff)
downloadchromium_src-54af05f8ea8050e0ab93dbcc940ac4e1bc4068e5.zip
chromium_src-54af05f8ea8050e0ab93dbcc940ac4e1bc4068e5.tar.gz
chromium_src-54af05f8ea8050e0ab93dbcc940ac4e1bc4068e5.tar.bz2
Add sync context dispatch restriction.
This adds a way to restrict on a per-channel basis that incoming messages may only be dispatched when that particular channel is sending a sync message (or in a message loop). It does so to the PPAPI channels, which may not introduce a sync dependency circle. BUG=chromiumos:13821 TEST=news.google.com with Pepper Flash (see bug) Review URL: http://codereview.chromium.org/6810013 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80892 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/ipc_sync_channel.cc')
-rw-r--r--ipc/ipc_sync_channel.cc36
1 files changed, 25 insertions, 11 deletions
diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc
index 1c7edfa..3dcab2c 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(),