summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorrockot <rockot@chromium.org>2015-08-05 17:32:29 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-06 00:32:58 +0000
commitac64ae92ff624f1befe3b973e0f0fd0204f2eac1 (patch)
tree5bea405e1851c88caac237c9edbcc6edf3361ac0 /ipc
parentf4acab417af4a182dbbb6bbc5aa1235662a9253c (diff)
downloadchromium_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.cc4
-rw-r--r--ipc/ipc_channel_proxy.h3
-rw-r--r--ipc/ipc_sync_channel.cc8
-rw-r--r--ipc/ipc_sync_channel.h6
-rw-r--r--ipc/ipc_sync_channel_unittest.cc2
-rw-r--r--ipc/ipc_sync_message_filter.cc19
-rw-r--r--ipc/ipc_sync_message_filter.h11
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_;