| 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..7b9b549357de20b2639ae467eec24f26d7ca7eaf 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(IPC::Message* message, bool send_now) {
|
| + return process_->SendImpl(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(message, send_now_);
|
| + }
|
| +
|
| + 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),
|
| @@ -1015,6 +1064,45 @@ void RenderProcessHostImpl::CreateMessageFilters() {
|
| }
|
| }
|
|
|
| +bool RenderProcessHostImpl::SendImpl(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()) {
|
| + 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;
|
| + }
|
| +
|
| + if (send_now)
|
| + return channel_->SendNow(msg);
|
| +
|
| + return channel_->SendOnIPCThread(msg);
|
| +}
|
| +
|
| void RenderProcessHostImpl::RegisterMojoServices() {
|
| #if !defined(OS_ANDROID)
|
| mojo_application_host_->service_registry()->AddService(
|
| @@ -1642,39 +1730,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(msg, false /* send_now */);
|
| }
|
|
|
| bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
|
| @@ -2030,6 +2086,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());
|
| }
|
|
|