Index: ipc/ipc_channel_proxy.cc |
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc |
index 64fab8fca56db0067e909aa5f96d2fe04443e912..88e3f051c71d161998bf4af5e224ff461eae10b6 100644 |
--- a/ipc/ipc_channel_proxy.cc |
+++ b/ipc/ipc_channel_proxy.cc |
@@ -30,6 +30,7 @@ ChannelProxy::Context::Context( |
ipc_task_runner_(ipc_task_runner), |
channel_connected_called_(false), |
message_filter_router_(new MessageFilterRouter()), |
+ channel_send_thread_safe_(false), |
peer_pid_(base::kNullProcessId) { |
DCHECK(ipc_task_runner_.get()); |
// The Listener thread where Messages are handled must be a separate thread |
@@ -54,6 +55,7 @@ void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) { |
DCHECK(!channel_); |
channel_id_ = factory->GetName(); |
channel_ = factory->BuildChannel(this); |
+ channel_send_thread_safe_ = channel_->IsSendThreadSafe(); |
} |
bool ChannelProxy::Context::TryFilters(const Message& message) { |
@@ -155,7 +157,7 @@ void ChannelProxy::Context::OnChannelClosed() { |
// access it any more. |
pending_filters_.clear(); |
- channel_.reset(); |
+ ClearChannel(); |
// Balance with the reference taken during startup. This may result in |
// self-destruction. |
@@ -303,6 +305,30 @@ void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) { |
listener_->OnBadMessageReceived(message); |
} |
+void ChannelProxy::Context::ClearChannel() { |
+ base::AutoLock l(channel_lifetime_lock_); |
+ channel_.reset(); |
+} |
+ |
+void ChannelProxy::Context::SendFromThisThread(Message* message) { |
+ base::AutoLock l(channel_lifetime_lock_); |
+ if (!channel_) |
+ return; |
+ DCHECK(channel_->IsSendThreadSafe()); |
+ channel_->Send(message); |
+} |
+ |
+void ChannelProxy::Context::Send(Message* message) { |
+ if (channel_send_thread_safe_) { |
+ SendFromThisThread(message); |
+ return; |
+ } |
+ |
+ ipc_task_runner()->PostTask( |
+ FROM_HERE, base::Bind(&ChannelProxy::Context::OnSendMessage, this, |
+ base::Passed(scoped_ptr<Message>(message)))); |
+} |
+ |
//----------------------------------------------------------------------------- |
// static |
@@ -407,10 +433,7 @@ bool ChannelProxy::Send(Message* message) { |
Logging::GetInstance()->OnSendMessage(message, context_->channel_id()); |
#endif |
- context_->ipc_task_runner()->PostTask( |
- FROM_HERE, |
- base::Bind(&ChannelProxy::Context::OnSendMessage, |
- context_, base::Passed(scoped_ptr<Message>(message)))); |
+ context_->Send(message); |
return true; |
} |