diff options
author | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-08 03:38:21 +0000 |
---|---|---|
committer | piman@google.com <piman@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-08 03:38:21 +0000 |
commit | 54af05f8ea8050e0ab93dbcc940ac4e1bc4068e5 (patch) | |
tree | 3641af4c4223de9f6e742e95b2fc23da4f4ec380 /ipc/ipc_sync_channel.cc | |
parent | 5fda613da7a4cb0147bb7d7f9559b541cd45a266 (diff) | |
download | chromium_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.cc | 36 |
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(), |