diff options
author | rockot <rockot@chromium.org> | 2015-08-05 17:32:29 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-08-06 00:32:58 +0000 |
commit | ac64ae92ff624f1befe3b973e0f0fd0204f2eac1 (patch) | |
tree | 5bea405e1851c88caac237c9edbcc6edf3361ac0 /ipc | |
parent | f4acab417af4a182dbbb6bbc5aa1235662a9253c (diff) | |
download | chromium_src-ac64ae92ff624f1befe3b973e0f0fd0204f2eac1.zip chromium_src-ac64ae92ff624f1befe3b973e0f0fd0204f2eac1.tar.gz chromium_src-ac64ae92ff624f1befe3b973e0f0fd0204f2eac1.tar.bz2 |
Let IPC::SyncMessageFilter take advantage of thread-safe Send.
SyncMessageFilter is unnecessarily hopping to the IO thread
before writing to its underlying Sender when the underlying
Sender has a thread-safe Send implementation.
This fixes that.
BUG=516464
Review URL: https://codereview.chromium.org/1262253004
Cr-Commit-Position: refs/heads/master@{#342027}
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_channel_proxy.cc | 4 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.h | 3 | ||||
-rw-r--r-- | ipc/ipc_sync_channel.cc | 8 | ||||
-rw-r--r-- | ipc/ipc_sync_channel.h | 6 | ||||
-rw-r--r-- | ipc/ipc_sync_channel_unittest.cc | 2 | ||||
-rw-r--r-- | ipc/ipc_sync_message_filter.cc | 19 | ||||
-rw-r--r-- | ipc/ipc_sync_message_filter.h | 11 |
7 files changed, 43 insertions, 10 deletions
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 44fa42b..adb3d67 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -341,6 +341,10 @@ void ChannelProxy::Context::Send(Message* message) { base::Passed(scoped_ptr<Message>(message)))); } +bool ChannelProxy::Context::IsChannelSendThreadSafe() const { + return channel_send_thread_safe_; +} + //----------------------------------------------------------------------------- // static diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index 6ff5cc2..f9f7d31 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h @@ -187,6 +187,9 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // Sends |message| from appropriate thread. void Send(Message* message); + // Indicates if the underlying channel's Send is thread-safe. + bool IsChannelSendThreadSafe() const; + protected: friend class base::RefCountedThreadSafe<Context>; ~Context() override; diff --git a/ipc/ipc_sync_channel.cc b/ipc/ipc_sync_channel.cc index 35b88a7..845eccd 100644 --- a/ipc/ipc_sync_channel.cc +++ b/ipc/ipc_sync_channel.cc @@ -460,6 +460,14 @@ void SyncChannel::SetRestrictDispatchChannelGroup(int group) { sync_context()->set_restrict_dispatch_group(group); } +scoped_refptr<SyncMessageFilter> SyncChannel::CreateSyncMessageFilter() { + scoped_refptr<SyncMessageFilter> filter = new SyncMessageFilter( + sync_context()->shutdown_event(), + sync_context()->IsChannelSendThreadSafe()); + AddFilter(filter.get()); + return filter; +} + bool SyncChannel::Send(Message* message) { #ifdef IPC_MESSAGE_LOG_ENABLED std::string name; diff --git a/ipc/ipc_sync_channel.h b/ipc/ipc_sync_channel.h index 8b4b9a9..2fd1b11 100644 --- a/ipc/ipc_sync_channel.h +++ b/ipc/ipc_sync_channel.h @@ -15,6 +15,7 @@ #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_sync_message.h" +#include "ipc/ipc_sync_message_filter.h" namespace base { class WaitableEvent; @@ -116,6 +117,11 @@ class IPC_EXPORT SyncChannel : public ChannelProxy { // default) will be dispatched in any case. void SetRestrictDispatchChannelGroup(int group); + // Creates a new IPC::SyncMessageFilter and adds it to this SyncChannel. + // This should be used instead of directly constructing a new + // SyncMessageFilter. + scoped_refptr<IPC::SyncMessageFilter> CreateSyncMessageFilter(); + protected: class ReceivedSyncMsgQueue; friend class ReceivedSyncMsgQueue; diff --git a/ipc/ipc_sync_channel_unittest.cc b/ipc/ipc_sync_channel_unittest.cc index 314a4b8..44218fd 100644 --- a/ipc/ipc_sync_channel_unittest.cc +++ b/ipc/ipc_sync_channel_unittest.cc @@ -950,7 +950,7 @@ class TestSyncMessageFilter : public SyncMessageFilter { base::WaitableEvent* shutdown_event, Worker* worker, scoped_refptr<base::SingleThreadTaskRunner> task_runner) - : SyncMessageFilter(shutdown_event), + : SyncMessageFilter(shutdown_event, false), worker_(worker), task_runner_(task_runner) {} diff --git a/ipc/ipc_sync_message_filter.cc b/ipc/ipc_sync_message_filter.cc index d86835d..f6d485d 100644 --- a/ipc/ipc_sync_message_filter.cc +++ b/ipc/ipc_sync_message_filter.cc @@ -15,17 +15,14 @@ namespace IPC { -SyncMessageFilter::SyncMessageFilter(base::WaitableEvent* shutdown_event) - : sender_(NULL), - listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), - shutdown_event_(shutdown_event) { -} - bool SyncMessageFilter::Send(Message* message) { if (!message->is_sync()) { { base::AutoLock auto_lock(lock_); - if (!io_task_runner_.get()) { + if (sender_ && is_channel_send_thread_safe_) { + sender_->Send(message); + return true; + } else if (!io_task_runner_.get()) { pending_messages_.push_back(message); return true; } @@ -112,6 +109,14 @@ bool SyncMessageFilter::OnMessageReceived(const Message& message) { return false; } +SyncMessageFilter::SyncMessageFilter(base::WaitableEvent* shutdown_event, + bool is_channel_send_thread_safe) + : sender_(NULL), + is_channel_send_thread_safe_(is_channel_send_thread_safe), + listener_task_runner_(base::ThreadTaskRunnerHandle::Get()), + shutdown_event_(shutdown_event) { +} + SyncMessageFilter::~SyncMessageFilter() { } diff --git a/ipc/ipc_sync_message_filter.h b/ipc/ipc_sync_message_filter.h index 32dffe3..2a3c4e8 100644 --- a/ipc/ipc_sync_message_filter.h +++ b/ipc/ipc_sync_message_filter.h @@ -21,6 +21,7 @@ class WaitableEvent; } namespace IPC { +class SyncChannel; // This MessageFilter allows sending synchronous IPC messages from a thread // other than the listener thread associated with the SyncChannel. It does not @@ -29,8 +30,6 @@ namespace IPC { // be used to send simultaneous synchronous messages from different threads. class IPC_EXPORT SyncMessageFilter : public MessageFilter, public Sender { public: - explicit SyncMessageFilter(base::WaitableEvent* shutdown_event); - // MessageSender implementation. bool Send(Message* message) override; @@ -41,9 +40,14 @@ class IPC_EXPORT SyncMessageFilter : public MessageFilter, public Sender { bool OnMessageReceived(const Message& message) override; protected: + SyncMessageFilter(base::WaitableEvent* shutdown_event, + bool is_channel_send_thread_safe); + ~SyncMessageFilter() override; private: + friend class SyncChannel; + void SendOnIOThread(Message* message); // Signal all the pending sends as done, used in an error condition. void SignalAllEvents(); @@ -51,6 +55,9 @@ class IPC_EXPORT SyncMessageFilter : public MessageFilter, public Sender { // The channel to which this filter was added. Sender* sender_; + // Indicates if |sender_|'s Send method is thread-safe. + bool is_channel_send_thread_safe_; + // The process's main thread. scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner_; |