Call RenderProcessHost::Send from correct thread (issue #1881)

This commit is contained in:
Marshall Greenblatt 2016-05-11 12:18:43 -04:00
parent 5b27df39b2
commit b90a3be186
5 changed files with 81 additions and 43 deletions

View File

@ -18,6 +18,7 @@
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
namespace { namespace {
@ -102,16 +103,16 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
// that happens re-visit the implementation of this class. // that happens re-visit the implementation of this class.
DCHECK_EQ(host, main_frame_host->GetProcess()); DCHECK_EQ(host, main_frame_host->GetProcess());
const int render_process_routing_id = host->GetID(); const int render_process_id = host->GetID();
const int render_view_routing_id = view_host->GetRoutingID(); const int render_view_routing_id = view_host->GetRoutingID();
const int render_frame_routing_id = main_frame_host->GetRoutingID(); const int render_frame_routing_id = main_frame_host->GetRoutingID();
scoped_refptr<CefBrowserInfo> browser_info = scoped_refptr<CefBrowserInfo> browser_info =
new CefBrowserInfo(++next_browser_id_, true); new CefBrowserInfo(++next_browser_id_, true);
browser_info->render_id_manager()->add_render_view_id( browser_info->render_id_manager()->add_render_view_id(
render_process_routing_id, render_view_routing_id); render_process_id, render_view_routing_id);
browser_info->render_id_manager()->add_render_frame_id( browser_info->render_id_manager()->add_render_frame_id(
render_process_routing_id, render_frame_routing_id); render_process_id, render_frame_routing_id);
browser_info_list_.push_back(browser_info); browser_info_list_.push_back(browser_info);
if (is_windowless) if (is_windowless)
@ -122,11 +123,11 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
pending_new_browser_info_list_.begin(); pending_new_browser_info_list_.begin();
for (; it != pending_new_browser_info_list_.end(); ++it) { for (; it != pending_new_browser_info_list_.end(); ++it) {
PendingNewBrowserInfo* info = *it; PendingNewBrowserInfo* info = *it;
if (info->host == host && if (info->render_process_id == render_process_id &&
info->render_view_routing_id == render_view_routing_id && info->render_view_routing_id == render_view_routing_id &&
info->render_frame_routing_id == render_frame_routing_id) { info->render_frame_routing_id == render_frame_routing_id) {
SendNewBrowserInfoResponse(host, browser_info.get(), false, SendNewBrowserInfoResponse(render_process_id, browser_info.get(),
info->reply_msg); false, info->reply_msg);
pending_new_browser_info_list_.erase(it); pending_new_browser_info_list_.erase(it);
break; break;
@ -137,15 +138,16 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
} }
void CefBrowserInfoManager::OnCreateWindow( void CefBrowserInfoManager::OnCreateWindow(
content::RenderProcessHost* host, int render_process_id,
const ViewHostMsg_CreateWindow_Params& params) { const ViewHostMsg_CreateWindow_Params& params) {
DCHECK_NE(render_process_id, content::ChildProcessHost::kInvalidUniqueID);
DCHECK_GT(params.opener_id, 0); DCHECK_GT(params.opener_id, 0);
DCHECK_GT(params.opener_render_frame_id, 0); DCHECK_GT(params.opener_render_frame_id, 0);
scoped_ptr<CefBrowserInfoManager::PendingPopup> pending_popup( scoped_ptr<CefBrowserInfoManager::PendingPopup> pending_popup(
new CefBrowserInfoManager::PendingPopup); new CefBrowserInfoManager::PendingPopup);
pending_popup->step = CefBrowserInfoManager::PendingPopup::ON_CREATE_WINDOW; pending_popup->step = CefBrowserInfoManager::PendingPopup::ON_CREATE_WINDOW;
pending_popup->opener_process_id = host->GetID(); pending_popup->opener_process_id = render_process_id;
pending_popup->opener_view_id = params.opener_id; pending_popup->opener_view_id = params.opener_id;
pending_popup->opener_frame_id = params.opener_render_frame_id; pending_popup->opener_frame_id = params.opener_render_frame_id;
pending_popup->target_url = params.target_url; pending_popup->target_url = params.target_url;
@ -312,29 +314,28 @@ void CefBrowserInfoManager::WebContentsCreated(
} }
void CefBrowserInfoManager::OnGetNewBrowserInfo( void CefBrowserInfoManager::OnGetNewBrowserInfo(
content::RenderProcessHost* host, int render_process_id,
int render_view_routing_id, int render_view_routing_id,
int render_frame_routing_id, int render_frame_routing_id,
IPC::Message* reply_msg) { IPC::Message* reply_msg) {
DCHECK(host); DCHECK_NE(render_process_id, content::ChildProcessHost::kInvalidUniqueID);
DCHECK_GT(render_view_routing_id, 0); DCHECK_GT(render_view_routing_id, 0);
DCHECK_GT(render_frame_routing_id, 0); DCHECK_GT(render_frame_routing_id, 0);
DCHECK(reply_msg); DCHECK(reply_msg);
base::AutoLock lock_scope(browser_info_lock_); base::AutoLock lock_scope(browser_info_lock_);
const int render_process_routing_id = host->GetID();
bool is_guest_view = false; bool is_guest_view = false;
scoped_refptr<CefBrowserInfo> browser_info = GetBrowserInfo( scoped_refptr<CefBrowserInfo> browser_info = GetBrowserInfo(
render_process_routing_id, render_view_routing_id, render_process_id, render_view_routing_id,
render_process_routing_id, render_frame_routing_id, render_process_id, render_frame_routing_id,
&is_guest_view); &is_guest_view);
if (browser_info.get()) { if (browser_info.get()) {
// Send the response immediately. // Send the response immediately.
SendNewBrowserInfoResponse(host, browser_info.get(), is_guest_view, SendNewBrowserInfoResponse(render_process_id, browser_info.get(),
reply_msg); is_guest_view, reply_msg);
return; return;
} }
@ -345,7 +346,7 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(
pending_new_browser_info_list_.begin(); pending_new_browser_info_list_.begin();
for (; it != pending_new_browser_info_list_.end(); ++it) { for (; it != pending_new_browser_info_list_.end(); ++it) {
PendingNewBrowserInfo* info = *it; PendingNewBrowserInfo* info = *it;
if (info->host == host && if (info->render_process_id == render_process_id &&
info->render_view_routing_id == render_view_routing_id && info->render_view_routing_id == render_view_routing_id &&
info->render_frame_routing_id == render_frame_routing_id) { info->render_frame_routing_id == render_frame_routing_id) {
NOTREACHED(); NOTREACHED();
@ -356,7 +357,7 @@ void CefBrowserInfoManager::OnGetNewBrowserInfo(
// Queue the request. // Queue the request.
scoped_ptr<PendingNewBrowserInfo> pending(new PendingNewBrowserInfo()); scoped_ptr<PendingNewBrowserInfo> pending(new PendingNewBrowserInfo());
pending->host = host; pending->render_process_id = render_process_id;
pending->render_view_routing_id = render_view_routing_id; pending->render_view_routing_id = render_view_routing_id;
pending->render_frame_routing_id = render_frame_routing_id; pending->render_frame_routing_id = render_frame_routing_id;
pending->reply_msg = reply_msg; pending->reply_msg = reply_msg;
@ -430,12 +431,14 @@ void CefBrowserInfoManager::RenderProcessHostDestroyed(
content::RenderProcessHost* host) { content::RenderProcessHost* host) {
base::AutoLock lock_scope(browser_info_lock_); base::AutoLock lock_scope(browser_info_lock_);
const int render_process_id = host->GetID();
// Remove all pending requests that reference the destroyed host. // Remove all pending requests that reference the destroyed host.
PendingNewBrowserInfoList::iterator it = PendingNewBrowserInfoList::iterator it =
pending_new_browser_info_list_.begin(); pending_new_browser_info_list_.begin();
while (it != pending_new_browser_info_list_.end()) { while (it != pending_new_browser_info_list_.end()) {
PendingNewBrowserInfo* info = *it; PendingNewBrowserInfo* info = *it;
if (info->host == host) if (info->render_process_id == render_process_id)
it = pending_new_browser_info_list_.erase(it); it = pending_new_browser_info_list_.erase(it);
else else
++it; ++it;
@ -445,10 +448,10 @@ void CefBrowserInfoManager::RenderProcessHostDestroyed(
void CefBrowserInfoManager::FilterPendingPopupURL( void CefBrowserInfoManager::FilterPendingPopupURL(
int render_process_id, int render_process_id,
scoped_ptr<CefBrowserInfoManager::PendingPopup> pending_popup) { scoped_ptr<CefBrowserInfoManager::PendingPopup> pending_popup) {
content::RenderProcessHost* rph = content::RenderProcessHost* host =
content::RenderProcessHost::FromID(render_process_id); content::RenderProcessHost::FromID(render_process_id);
DCHECK(rph); DCHECK(host);
rph->FilterURL(false, &pending_popup->target_url); host->FilterURL(false, &pending_popup->target_url);
GetInstance()->PushPendingPopup(std::move(pending_popup)); GetInstance()->PushPendingPopup(std::move(pending_popup));
} }
@ -541,10 +544,24 @@ scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfo(
// static // static
void CefBrowserInfoManager::SendNewBrowserInfoResponse( void CefBrowserInfoManager::SendNewBrowserInfoResponse(
content::RenderProcessHost* host, int render_process_id,
CefBrowserInfo* browser_info, CefBrowserInfo* browser_info,
bool is_guest_view, bool is_guest_view,
IPC::Message* reply_msg) { IPC::Message* reply_msg) {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(&CefBrowserInfoManager::SendNewBrowserInfoResponse,
render_process_id, browser_info, is_guest_view, reply_msg));
return;
}
content::RenderProcessHost* host =
content::RenderProcessHost::FromID(render_process_id);
if (!host) {
delete reply_msg;
return;
}
CefProcessHostMsg_GetNewBrowserInfo_Params params; CefProcessHostMsg_GetNewBrowserInfo_Params params;
params.browser_id = browser_info->browser_id(); params.browser_id = browser_info->browser_id();
params.is_windowless = browser_info->is_windowless(); params.is_windowless = browser_info->is_windowless();

View File

@ -60,7 +60,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Called from CefBrowserMessageFilter::OnCreateWindow. See comments on // Called from CefBrowserMessageFilter::OnCreateWindow. See comments on
// PendingPopup for more information. // PendingPopup for more information.
void OnCreateWindow(content::RenderProcessHost* host, void OnCreateWindow(int render_process_id,
const ViewHostMsg_CreateWindow_Params& params); const ViewHostMsg_CreateWindow_Params& params);
// Called from CefContentBrowserClient::CanCreateWindow. See comments on // Called from CefContentBrowserClient::CanCreateWindow. See comments on
@ -103,7 +103,7 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// already exist for traditional popup browsers depending on timing. See // already exist for traditional popup browsers depending on timing. See
// comments on PendingPopup for more information. // comments on PendingPopup for more information.
void OnGetNewBrowserInfo( void OnGetNewBrowserInfo(
content::RenderProcessHost* host, int render_process_id,
int render_view_routing_id, int render_view_routing_id,
int render_frame_routing_id, int render_frame_routing_id,
IPC::Message* reply_msg); IPC::Message* reply_msg);
@ -204,14 +204,14 @@ class CefBrowserInfoManager : public content::RenderProcessHostObserver {
// Send the response for a pending OnGetNewBrowserInfo request. // Send the response for a pending OnGetNewBrowserInfo request.
static void SendNewBrowserInfoResponse( static void SendNewBrowserInfoResponse(
content::RenderProcessHost* host, int render_process_id,
CefBrowserInfo* browser_info, CefBrowserInfo* browser_info,
bool is_guest_view, bool is_guest_view,
IPC::Message* reply_msg); IPC::Message* reply_msg);
// Pending request for OnGetNewBrowserInfo. // Pending request for OnGetNewBrowserInfo.
struct PendingNewBrowserInfo { struct PendingNewBrowserInfo {
content::RenderProcessHost* host; int render_process_id;
int render_view_routing_id; int render_view_routing_id;
int render_frame_routing_id; int render_frame_routing_id;
IPC::Message* reply_msg; IPC::Message* reply_msg;

View File

@ -1,4 +1,4 @@
/// Copyright (c) 2012 The Chromium Embedded Framework Authors. // Copyright (c) 2012 The Chromium Embedded Framework Authors.
// Portions (c) 2011 The Chromium Authors. All rights reserved. // Portions (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
@ -19,10 +19,10 @@
#include "content/common/frame_messages.h" #include "content/common/frame_messages.h"
#include "content/common/view_messages.h" #include "content/common/view_messages.h"
#include "content/public/browser/render_process_host.h" #include "content/public/browser/render_process_host.h"
#include "content/public/common/child_process_host.h"
CefBrowserMessageFilter::CefBrowserMessageFilter( CefBrowserMessageFilter::CefBrowserMessageFilter(int render_process_id)
content::RenderProcessHost* host) : render_process_id_(render_process_id),
: host_(host),
sender_(NULL) { sender_(NULL) {
} }
@ -34,7 +34,7 @@ void CefBrowserMessageFilter::OnFilterAdded(IPC::Sender* sender) {
} }
void CefBrowserMessageFilter::OnFilterRemoved() { void CefBrowserMessageFilter::OnFilterRemoved() {
host_ = NULL; render_process_id_ = content::ChildProcessHost::kInvalidUniqueID;
sender_ = NULL; sender_ = NULL;
} }
@ -63,7 +63,21 @@ bool CefBrowserMessageFilter::OnMessageReceived(const IPC::Message& message) {
} }
bool CefBrowserMessageFilter::Send(IPC::Message* message) { bool CefBrowserMessageFilter::Send(IPC::Message* message) {
return host_->Send(message); if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(CEF_UIT,
base::Bind(base::IgnoreResult(&CefBrowserMessageFilter::Send), this,
message));
return true;
}
content::RenderProcessHost* host =
content::RenderProcessHost::FromID(render_process_id_);
if (!host) {
delete message;
return false;
}
return host->Send(message);
} }
void CefBrowserMessageFilter::OnGetNewRenderThreadInfo( void CefBrowserMessageFilter::OnGetNewRenderThreadInfo(
@ -87,17 +101,24 @@ void CefBrowserMessageFilter::OnGetNewBrowserInfo(
int render_view_routing_id, int render_view_routing_id,
int render_frame_routing_id, int render_frame_routing_id,
IPC::Message* reply_msg) { IPC::Message* reply_msg) {
if (render_process_id_ != content::ChildProcessHost::kInvalidUniqueID) {
CefBrowserInfoManager::GetInstance()->OnGetNewBrowserInfo( CefBrowserInfoManager::GetInstance()->OnGetNewBrowserInfo(
host_, render_process_id_,
render_view_routing_id, render_view_routing_id,
render_frame_routing_id, render_frame_routing_id,
reply_msg); reply_msg);
} else {
delete reply_msg;
}
} }
void CefBrowserMessageFilter::OnCreateWindow( void CefBrowserMessageFilter::OnCreateWindow(
const ViewHostMsg_CreateWindow_Params& params, const ViewHostMsg_CreateWindow_Params& params,
IPC::Message* reply_msg) { IPC::Message* reply_msg) {
CefBrowserInfoManager::GetInstance()->OnCreateWindow(host_, params); if (render_process_id_ != content::ChildProcessHost::kInvalidUniqueID) {
CefBrowserInfoManager::GetInstance()->OnCreateWindow(render_process_id_,
params);
}
// Reply message is not used. // Reply message is not used.
delete reply_msg; delete reply_msg;
@ -111,11 +132,11 @@ void CefBrowserMessageFilter::OnFrameFocused(int32_t render_frame_routing_id) {
return; return;
} }
if (!host_) if (render_process_id_ == content::ChildProcessHost::kInvalidUniqueID)
return; return;
CefRefPtr<CefBrowserHostImpl> browser = CefRefPtr<CefBrowserHostImpl> browser =
CefBrowserHostImpl::GetBrowserForFrame(host_->GetID(), CefBrowserHostImpl::GetBrowserForFrame(render_process_id_,
render_frame_routing_id); render_frame_routing_id);
if (browser.get()) if (browser.get())
browser->SetFocusedFrame(render_frame_routing_id); browser->SetFocusedFrame(render_frame_routing_id);

View File

@ -24,7 +24,7 @@ struct ViewHostMsg_CreateWindow_Params;
// This class sends and receives control messages on the browser process. // This class sends and receives control messages on the browser process.
class CefBrowserMessageFilter : public IPC::MessageFilter { class CefBrowserMessageFilter : public IPC::MessageFilter {
public: public:
explicit CefBrowserMessageFilter(content::RenderProcessHost* host); explicit CefBrowserMessageFilter(int render_process_id);
~CefBrowserMessageFilter() override; ~CefBrowserMessageFilter() override;
// IPC::ChannelProxy::MessageFilter implementation. // IPC::ChannelProxy::MessageFilter implementation.
@ -46,7 +46,7 @@ class CefBrowserMessageFilter : public IPC::MessageFilter {
IPC::Message* reply_msg); IPC::Message* reply_msg);
void OnFrameFocused(int32_t render_frame_routing_id); void OnFrameFocused(int32_t render_frame_routing_id);
content::RenderProcessHost* host_; int render_process_id_;
IPC::Sender* sender_; IPC::Sender* sender_;
DISALLOW_COPY_AND_ASSIGN(CefBrowserMessageFilter); DISALLOW_COPY_AND_ASSIGN(CefBrowserMessageFilter);

View File

@ -434,7 +434,7 @@ void CefContentBrowserClient::RenderProcessWillLaunch(
base::CommandLine::ForCurrentProcess(); base::CommandLine::ForCurrentProcess();
const int id = host->GetID(); const int id = host->GetID();
host->GetChannel()->AddFilter(new CefBrowserMessageFilter(host)); host->GetChannel()->AddFilter(new CefBrowserMessageFilter(id));
host->AddFilter(new printing::PrintingMessageFilter(id)); host->AddFilter(new printing::PrintingMessageFilter(id));
if (!command_line->HasSwitch(switches::kDisableSpellChecking)) { if (!command_line->HasSwitch(switches::kDisableSpellChecking)) {