Chromium Code Reviews| Index: content/browser/renderer_host/render_process_host_impl.cc |
| diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc |
| index 2ee3b3341f4d37f1a88e6a93bdab2075dc9e28e0..2cf760f634f0d3d85f06408c1add1260b96fa7be 100644 |
| --- a/content/browser/renderer_host/render_process_host_impl.cc |
| +++ b/content/browser/renderer_host/render_process_host_impl.cc |
| @@ -164,6 +164,7 @@ |
| #include "ipc/attachment_broker_privileged.h" |
| #include "ipc/ipc_channel.h" |
| #include "ipc/ipc_logging.h" |
| +#include "ipc/ipc_sender.h" |
| #include "ipc/ipc_switches.h" |
| #include "ipc/mojo/ipc_channel_mojo.h" |
| #include "media/base/media_switches.h" |
| @@ -447,6 +448,53 @@ std::string UintVectorToString(const std::vector<unsigned>& vector) { |
| } // namespace |
| +// SafeSenderProxy owns two IPC::Sender implementations which proxy to the |
| +// RPH's own ChannelProxy. One enables immediate sends while the other enables |
| +// IO-thread sends. These are both implemented via RPHI's SendImpl which safely |
| +// avoids dereferencing the underlying ChannelProxy if it's been reset (e.g. |
| +// after process death.) |
| +class RenderProcessHostImpl::SafeSenderProxy { |
| + public: |
| + // |process| must outlive this object. |
| + explicit SafeSenderProxy(RenderProcessHostImpl* process) |
| + : process_(process), |
| + immediate_sender_(this, true /* send_now */), |
| + io_thread_sender_(this, false /* send_now */) {} |
| + ~SafeSenderProxy() {} |
| + |
| + IPC::Sender* immediate_sender() { return &immediate_sender_; } |
| + IPC::Sender* io_thread_sender() { return &io_thread_sender_; } |
| + |
| + bool SendImpl(std::unique_ptr<IPC::Message> message, bool send_now) { |
| + return process_->SendImpl(std::move(message), send_now); |
| + } |
| + |
| + private: |
| + class SenderProxy : public IPC::Sender { |
| + public: |
| + SenderProxy(SafeSenderProxy* safe_proxy, bool send_now) |
| + : safe_proxy_(safe_proxy), send_now_(send_now) {} |
| + ~SenderProxy() override {} |
| + |
| + // IPC::Sender: |
| + bool Send(IPC::Message* message) override { |
| + return safe_proxy_->SendImpl(base::WrapUnique(message), send_now_); |
|
Charlie Reis
2016/05/23 23:33:12
Is there a reason not to just store process_ on Se
|
| + } |
| + |
| + private: |
| + SafeSenderProxy* const safe_proxy_; |
| + const bool send_now_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SenderProxy); |
| + }; |
| + |
| + RenderProcessHostImpl* process_; |
| + SenderProxy immediate_sender_; |
| + SenderProxy io_thread_sender_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SafeSenderProxy); |
| +}; |
| + |
| RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; |
| base::MessageLoop* g_in_process_thread; |
| @@ -536,6 +584,7 @@ RenderProcessHostImpl::RenderProcessHostImpl( |
| is_self_deleted_(false), |
| #endif |
| pending_views_(0), |
| + safe_sender_(new SafeSenderProxy(this)), |
| mojo_application_host_(new MojoApplicationHost), |
| visible_widgets_(0), |
| is_process_backgrounded_(false), |
| @@ -648,10 +697,8 @@ RenderProcessHostImpl::~RenderProcessHostImpl() { |
| #endif |
| // We may have some unsent messages at this point, but that's OK. |
| channel_.reset(); |
| - while (!queued_messages_.empty()) { |
| - delete queued_messages_.front(); |
| + while (!queued_messages_.empty()) |
| queued_messages_.pop(); |
| - } |
| UnregisterHost(GetID()); |
| @@ -1015,6 +1062,41 @@ void RenderProcessHostImpl::CreateMessageFilters() { |
| } |
| } |
| +bool RenderProcessHostImpl::SendImpl(std::unique_ptr<IPC::Message> msg, |
| + bool send_now) { |
| + TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::SendImpl"); |
| +#if !defined(OS_ANDROID) |
| + DCHECK(!msg->is_sync()); |
| +#endif |
| + |
| + if (!channel_) { |
| +#if defined(OS_ANDROID) |
| + if (msg->is_sync()) |
| + return false; |
| +#endif |
| + if (!is_initialized_) { |
| + queued_messages_.emplace(std::move(msg)); |
| + return true; |
| + } else { |
| + return false; |
| + } |
| + } |
| + |
| + if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) { |
| +#if defined(OS_ANDROID) |
| + if (msg->is_sync()) |
| + return false; |
| +#endif |
| + queued_messages_.emplace(std::move(msg)); |
| + return true; |
| + } |
| + |
| + if (send_now) |
| + return channel_->SendNow(std::move(msg)); |
| + |
| + return channel_->SendOnIPCThread(std::move(msg)); |
| +} |
| + |
| void RenderProcessHostImpl::RegisterMojoServices() { |
| #if !defined(OS_ANDROID) |
| mojo_application_host_->service_registry()->AddService( |
| @@ -1642,39 +1724,7 @@ bool RenderProcessHostImpl::FastShutdownIfPossible() { |
| } |
| bool RenderProcessHostImpl::Send(IPC::Message* msg) { |
| - TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send"); |
| -#if !defined(OS_ANDROID) |
| - DCHECK(!msg->is_sync()); |
| -#endif |
| - |
| - if (!channel_) { |
| -#if defined(OS_ANDROID) |
| - if (msg->is_sync()) { |
| - delete msg; |
| - return false; |
| - } |
| -#endif |
| - if (!is_initialized_) { |
| - queued_messages_.push(msg); |
| - return true; |
| - } else { |
| - delete msg; |
| - return false; |
| - } |
| - } |
| - |
| - if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) { |
| -#if defined(OS_ANDROID) |
| - if (msg->is_sync()) { |
| - delete msg; |
| - return false; |
| - } |
| -#endif |
| - queued_messages_.push(msg); |
| - return true; |
| - } |
| - |
| - return channel_->Send(msg); |
| + return SendImpl(base::WrapUnique(msg), false /* send_now */); |
| } |
| bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) { |
| @@ -2030,6 +2080,14 @@ IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() { |
| return channel_.get(); |
| } |
| +IPC::Sender* RenderProcessHostImpl::GetImmediateSender() { |
| + return safe_sender_->immediate_sender(); |
| +} |
| + |
| +IPC::Sender* RenderProcessHostImpl::GetIOThreadSender() { |
| + return safe_sender_->io_thread_sender(); |
| +} |
| + |
| void RenderProcessHostImpl::AddFilter(BrowserMessageFilter* filter) { |
| channel_->AddFilter(filter->GetFilter()); |
| } |
| @@ -2375,10 +2433,8 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead, |
| channel_.get()); |
| #endif |
| channel_.reset(); |
| - while (!queued_messages_.empty()) { |
| - delete queued_messages_.front(); |
| + while (!queued_messages_.empty()) |
| queued_messages_.pop(); |
| - } |
| UpdateProcessPriority(); |
| DCHECK(!is_process_backgrounded_); |
| @@ -2555,7 +2611,7 @@ void RenderProcessHostImpl::OnProcessLaunched() { |
| NotificationService::NoDetails()); |
| while (!queued_messages_.empty()) { |
| - Send(queued_messages_.front()); |
| + Send(queued_messages_.front().release()); |
| queued_messages_.pop(); |
| } |