summaryrefslogtreecommitdiffstats
path: root/chrome/plugin/plugin_channel_base.h
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 20:32:52 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-12 20:32:52 +0000
commit390c7814321cb6708a6979daecd0c727c38b7695 (patch)
tree62fc029b7aeea74a8b8bd93e998bed9b841c79cd /chrome/plugin/plugin_channel_base.h
parenta669333ec5caf533bc52c8aa68d6110630835b54 (diff)
downloadchromium_src-390c7814321cb6708a6979daecd0c727c38b7695.zip
chromium_src-390c7814321cb6708a6979daecd0c727c38b7695.tar.gz
chromium_src-390c7814321cb6708a6979daecd0c727c38b7695.tar.bz2
Fix possible deadlock in PluginChannel.
This occurs when the renderer sends an async message with the unblock flag, and then a sync message right after. If the plugin process just made a sync (with no unblock) call to the renderer, it'll dispatch the first message, and if that leads to a sync call to the renderer, then the unblock flag won't get sent and a deadlock occurs. BUG=43617 Review URL: http://codereview.chromium.org/2045012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47063 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/plugin/plugin_channel_base.h')
-rw-r--r--chrome/plugin/plugin_channel_base.h25
1 files changed, 17 insertions, 8 deletions
diff --git a/chrome/plugin/plugin_channel_base.h b/chrome/plugin/plugin_channel_base.h
index 079dcc5..b1f5e3d 100644
--- a/chrome/plugin/plugin_channel_base.h
+++ b/chrome/plugin/plugin_channel_base.h
@@ -94,9 +94,9 @@ class PluginChannelBase : public IPC::Channel::Listener,
virtual void OnChannelConnected(int32 peer_pid);
virtual void OnChannelError();
- // If this is set, sync messages that are sent will only unblock the receiver
- // if this channel is in the middle of a sync dispatch.
- void SendUnblockingOnlyDuringSyncDispatch();
+ void set_send_unblocking_only_during_unblock_dispatch() {
+ send_unblocking_only_during_unblock_dispatch_ = true;
+ }
virtual bool Init(MessageLoop* ipc_message_loop, bool create_pipe_now);
@@ -124,13 +124,22 @@ class PluginChannelBase : public IPC::Channel::Listener,
// error. This flag is used to indicate the same.
bool channel_valid_;
- // Track whether we're within a synchronous dispatch; works like a refcount,
- // 0 when we're not.
- int in_sync_dispatch_;
+ // Track whether we're dispatching a message with the unblock flag; works like
+ // a refcount, 0 when we're not.
+ int in_unblock_dispatch_;
// If true, sync messages will only be marked as unblocking if the channel is
- // in the middle of dispatching a synchronous message.
- bool send_unblocking_only_during_sync_dispatch_;
+ // in the middle of dispatching an unblocking message.
+ // The plugin process wants to avoid setting the unblock flag on its sync
+ // messages unless necessary, since it can potentially introduce reentrancy
+ // into WebKit in ways that it doesn't expect (i.e. causing layoutout during
+ // paint). However to avoid deadlock, we must ensure that any message that's
+ // sent as a result of a sync call from the renderer must unblock the
+ // renderer. We additionally have to do this for async messages from the
+ // renderer that have the unblock flag set, since they could be followed by a
+ // sync message that won't get dispatched until the call to the renderer is
+ // complete.
+ bool send_unblocking_only_during_unblock_dispatch_;
DISALLOW_COPY_AND_ASSIGN(PluginChannelBase);
};