diff options
Diffstat (limited to 'chrome/browser')
25 files changed, 193 insertions, 200 deletions
diff --git a/chrome/browser/cert_store.cc b/chrome/browser/cert_store.cc index 7d6221b..7687a9f 100644 --- a/chrome/browser/cert_store.cc +++ b/chrome/browser/cert_store.cc @@ -138,5 +138,5 @@ void CertStore::Observe(NotificationType type, DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED); RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr(); DCHECK(rph); - RemoveCertsForRenderProcesHost(rph->host_id()); + RemoveCertsForRenderProcesHost(rph->pid()); } diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index b50e039..719efa0 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -1050,7 +1050,7 @@ void DownloadManager::DownloadUrl(const GURL& url, DCHECK(web_contents); file_manager_->DownloadUrl(url, referrer, - web_contents->process()->host_id(), + web_contents->process()->pid(), web_contents->render_view_host()->routing_id(), request_context_.get()); } diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc index 158432d..d81e44b 100644 --- a/chrome/browser/download/save_package.cc +++ b/chrome/browser/download/save_package.cc @@ -156,7 +156,7 @@ SavePackage::SavePackage(WebContents* web_content, save_type_(save_type), all_save_items_count_(0), wait_state_(INITIALIZE), - tab_id_(web_content->process()->host_id()) { + tab_id_(web_content->process()->pid()) { DCHECK(web_content); const GURL& current_page_url = web_contents_->GetURL(); DCHECK(current_page_url.is_valid()); @@ -578,7 +578,7 @@ void SavePackage::CheckFinish() { &SaveFileManager::RenameAllFiles, final_names, dir, - web_contents_->process()->host_id(), + web_contents_->process()->pid(), web_contents_->render_view_host()->routing_id())); } @@ -716,7 +716,7 @@ void SavePackage::SaveNextFile(bool process_all_remaining_items) { save_item->Start(); file_manager_->SaveURL(save_item->url(), save_item->referrer(), - web_contents_->process()->host_id(), + web_contents_->process()->pid(), web_contents_->render_view_host()->routing_id(), save_item->save_source(), save_item->full_path(), diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 1ac8c73..f6a992e7 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -372,7 +372,7 @@ PluginProcessHost::PluginProcessHost(MessageLoop* main_message_loop) PluginProcessHost::~PluginProcessHost() { // Cancel all requests for plugin process. PluginService::GetInstance()->resource_dispatcher_host()-> - CancelRequestsForProcess(-1); + CancelRequestsForProcess(pid()); #if defined(OS_WIN) // We erase HWNDs from the plugin_parent_windows_set_ when we receive a @@ -618,23 +618,23 @@ void PluginProcessHost::OnRequestResource( PluginService::GetInstance()->resource_dispatcher_host()-> BeginRequest(this, ChildProcessInfo::PLUGIN_PROCESS, handle(), - -1, MSG_ROUTING_CONTROL, request_id, + pid(), MSG_ROUTING_CONTROL, request_id, request, context, NULL); } void PluginProcessHost::OnCancelRequest(int request_id) { PluginService::GetInstance()->resource_dispatcher_host()-> - CancelRequest(-1, request_id, true); + CancelRequest(pid(), request_id, true); } void PluginProcessHost::OnDataReceivedACK(int request_id) { PluginService::GetInstance()->resource_dispatcher_host()-> - OnDataReceivedACK(-1, request_id); + OnDataReceivedACK(pid(), request_id); } void PluginProcessHost::OnUploadProgressACK(int request_id) { PluginService::GetInstance()->resource_dispatcher_host()-> - OnUploadProgressACK(-1, request_id); + OnUploadProgressACK(pid(), request_id); } void PluginProcessHost::OnSyncLoad( @@ -649,7 +649,7 @@ void PluginProcessHost::OnSyncLoad( PluginService::GetInstance()->resource_dispatcher_host()-> BeginRequest(this, ChildProcessInfo::PLUGIN_PROCESS, handle(), - -1, MSG_ROUTING_CONTROL, request_id, + pid(), MSG_ROUTING_CONTROL, request_id, request, context, sync_result); } @@ -703,23 +703,11 @@ void PluginProcessHost::RequestPluginChannel( // plugin process (i.e. unblocks a Send() call like a sync message) otherwise // a deadlock can occur if the plugin creation request from the renderer is // a result of a sync message by the plugin process. - - // The plugin process expects to receive a handle to the renderer requesting - // the channel. The handle has to be valid in the plugin process. - HANDLE renderer_handle = NULL; - BOOL result = DuplicateHandle(GetCurrentProcess(), - renderer_message_filter->renderer_handle(), - handle(), &renderer_handle, 0, FALSE, - DUPLICATE_SAME_ACCESS); - DCHECK(result); - - PluginProcessMsg_CreateChannel* msg = - new PluginProcessMsg_CreateChannel( - renderer_message_filter->render_process_host_id(), renderer_handle); + PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel(); msg->set_unblock(true); if (Send(msg)) { - sent_requests_.push_back(ChannelRequest(renderer_message_filter, mime_type, - reply_msg)); + sent_requests_.push(ChannelRequest( + renderer_message_filter, mime_type, reply_msg)); } else { ReplyToRenderer(renderer_message_filter, std::wstring(), FilePath(), reply_msg); @@ -730,22 +718,12 @@ void PluginProcessHost::RequestPluginChannel( #endif } -void PluginProcessHost::OnChannelCreated(int process_id, - const std::wstring& channel_name) { - for (size_t i = 0; i < sent_requests_.size(); ++i) { - if (sent_requests_[i].renderer_message_filter_->render_process_host_id() - == process_id) { - ReplyToRenderer(sent_requests_[i].renderer_message_filter_.get(), - channel_name, - info_.path, - sent_requests_[i].reply_msg); - - sent_requests_.erase(sent_requests_.begin() + i); - return; - } - } - - NOTREACHED(); +void PluginProcessHost::OnChannelCreated(const std::wstring& channel_name) { + ReplyToRenderer(sent_requests_.front().renderer_message_filter_.get(), + channel_name, + info_.path, + sent_requests_.front().reply_msg); + sent_requests_.pop(); } void PluginProcessHost::OnDownloadUrl(const std::string& url, diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 48c05e9f..6885092 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -8,6 +8,7 @@ #include "build/build_config.h" #include <set> +#include <queue> #include <vector> #include "base/basictypes.h" @@ -94,7 +95,7 @@ class PluginProcessHost : public ChildProcessHost, const std::string& mime_type, IPC::Message* reply_msg); // Message handlers. - void OnChannelCreated(int process_id, const std::wstring& channel_name); + void OnChannelCreated(const std::wstring& channel_name); void OnDownloadUrl(const std::string& url, int source_pid, gfx::NativeWindow caller_window); void OnGetPluginFinderUrl(std::string* plugin_finder_url); @@ -134,7 +135,7 @@ class PluginProcessHost : public ChildProcessHost, // These are the channel requests that we have already sent to // the plugin process, but haven't heard back about yet. - std::vector<ChannelRequest> sent_requests_; + std::queue<ChannelRequest> sent_requests_; // Information about the plugin. WebPluginInfo info_; diff --git a/chrome/browser/renderer_host/async_resource_handler.cc b/chrome/browser/renderer_host/async_resource_handler.cc index 650c7c3..73aa227 100644 --- a/chrome/browser/renderer_host/async_resource_handler.cc +++ b/chrome/browser/renderer_host/async_resource_handler.cc @@ -35,15 +35,15 @@ class SharedIOBuffer : public net::IOBuffer { AsyncResourceHandler::AsyncResourceHandler( ResourceDispatcherHost::Receiver* receiver, - int render_process_host_id, + int process_id, int routing_id, - base::ProcessHandle render_process, + base::ProcessHandle process_handle, const GURL& url, ResourceDispatcherHost* resource_dispatcher_host) : receiver_(receiver), - render_process_host_id_(render_process_host_id), + process_id_(process_id), routing_id_(routing_id), - render_process_(render_process), + process_handle_(process_handle), rdh_(resource_dispatcher_host) { } @@ -91,18 +91,18 @@ bool AsyncResourceHandler::OnReadCompleted(int request_id, int* bytes_read) { return true; DCHECK(read_buffer_.get()); - if (!rdh_->WillSendData(render_process_host_id_, request_id)) { + if (!rdh_->WillSendData(process_id_, request_id)) { // We should not send this data now, we have too many pending requests. return true; } base::SharedMemoryHandle handle; - if (!read_buffer_->shared_memory()->GiveToProcess(render_process_, &handle)) { + if (!read_buffer_->shared_memory()->GiveToProcess(process_handle_, &handle)) { // We wrongfully incremented the pending data count. Fake an ACK message // to fix this. We can't move this call above the WillSendData because // it's killing our read_buffer_, and we don't want that when we pause // the request. - rdh_->OnDataReceivedACK(render_process_host_id_, request_id); + rdh_->OnDataReceivedACK(process_id_, request_id); // We just unmapped the memory. read_buffer_ = NULL; return false; diff --git a/chrome/browser/renderer_host/async_resource_handler.h b/chrome/browser/renderer_host/async_resource_handler.h index 7407e6d..cfb9fc5 100644 --- a/chrome/browser/renderer_host/async_resource_handler.h +++ b/chrome/browser/renderer_host/async_resource_handler.h @@ -18,9 +18,9 @@ class SharedIOBuffer; class AsyncResourceHandler : public ResourceHandler { public: AsyncResourceHandler(ResourceDispatcherHost::Receiver* receiver, - int render_process_host_id, + int process_id, int routing_id, - base::ProcessHandle render_process, + base::ProcessHandle process_handle, const GURL& url, ResourceDispatcherHost* resource_dispatcher_host); @@ -45,9 +45,9 @@ class AsyncResourceHandler : public ResourceHandler { scoped_refptr<SharedIOBuffer> read_buffer_; ResourceDispatcherHost::Receiver* receiver_; - int render_process_host_id_; + int process_id_; int routing_id_; - base::ProcessHandle render_process_; + base::ProcessHandle process_handle_; ResourceDispatcherHost* rdh_; DISALLOW_COPY_AND_ASSIGN(AsyncResourceHandler); diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index fd5ba33..a3171e3 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -128,12 +128,7 @@ BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_( base::TimeDelta::FromSeconds(5), this, &BrowserRenderProcessHost::ClearTransportDIBCache)) { - DCHECK(host_id() >= 0); // We use a negative host_id_ in destruction. - widget_helper_ = new RenderWidgetHelper( - host_id(), g_browser_process->resource_dispatcher_host()); - - CacheManagerHost::GetInstance()->Add(host_id()); - RendererSecurityPolicy::GetInstance()->Add(host_id()); + widget_helper_ = new RenderWidgetHelper(); PrefService* prefs = profile->GetPrefs(); prefs->AddPrefObserver(prefs::kBlockPopups, this); @@ -151,9 +146,10 @@ BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) } BrowserRenderProcessHost::~BrowserRenderProcessHost() { - // Some tests hold BrowserRenderProcessHost in a scoped_ptr, so we must call - // Unregister here as well as in response to Release(). - Unregister(); + if (pid() >= 0) { + CacheManagerHost::GetInstance()->Remove(pid()); + RendererSecurityPolicy::GetInstance()->Remove(pid()); + } // We may have some unsent messages at this point, but that's OK. channel_.reset(); @@ -192,7 +188,6 @@ bool BrowserRenderProcessHost::Init() { audio_renderer_host_.get(), PluginService::GetInstance(), g_browser_process->print_job_manager(), - host_id(), profile(), widget_helper_, profile()->GetSpellChecker()); @@ -306,6 +301,7 @@ bool BrowserRenderProcessHost::Init() { cmd_line.AppendSwitchWithValue(switches::kUserDataDir, profile_path); + int process_id; bool run_in_process = run_renderer_in_process(); if (run_in_process) { // Crank up a thread and run the initialization there. With the way that @@ -323,6 +319,14 @@ bool BrowserRenderProcessHost::Init() { base::Thread::Options options; options.message_loop_type = MessageLoop::TYPE_IO; in_process_renderer_->StartWithOptions(options); + + // We need a "renderer pid", but we don't have one when there's no renderer + // process. So pick a value that won't clash with other child process pids. + // Linux has PID_MAX_LIMIT which is 2^22. Windows always uses pids that are + // divisible by 4. So... + static int next_pid = 4 * 1024 * 1024; + next_pid += 3; + process_id = next_pid; } else { #if defined(OS_WIN) if (in_sandbox) { @@ -405,8 +409,15 @@ bool BrowserRenderProcessHost::Init() { return false; process_.set_handle(process); } + + process_id = process_.pid(); } + SetProcessID(process_id); + resource_message_filter->Init(pid()); + CacheManagerHost::GetInstance()->Add(pid()); + RendererSecurityPolicy::GetInstance()->Add(pid()); + // Now that the process is created, set it's backgrounding accordingly. SetBackgrounded(backgrounded_); @@ -771,17 +782,6 @@ void BrowserRenderProcessHost::OnChannelError() { // TODO(darin): clean this up } -void BrowserRenderProcessHost::Unregister() { - // RenderProcessHost::Unregister will clean up the host_id_, so we must - // do our cleanup that uses that variable before we call it. - if (host_id() >= 0) { - CacheManagerHost::GetInstance()->Remove(host_id()); - RendererSecurityPolicy::GetInstance()->Remove(host_id()); - } - - RenderProcessHost::Unregister(); -} - void BrowserRenderProcessHost::OnPageContents(const GURL& url, int32 page_id, const std::wstring& contents) { @@ -796,7 +796,7 @@ void BrowserRenderProcessHost::OnPageContents(const GURL& url, void BrowserRenderProcessHost::OnUpdatedCacheStats( const CacheManager::UsageStats& stats) { - CacheManagerHost::GetInstance()->ObserveStats(host_id(), stats); + CacheManagerHost::GetInstance()->ObserveStats(pid(), stats); } void BrowserRenderProcessHost::SetBackgrounded(bool backgrounded) { diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index 556bbfc..7e149ce 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -87,9 +87,6 @@ class BrowserRenderProcessHost : public RenderProcessHost, const NotificationDetails& details); private: - // RenderProcessHost implementation (protected portion). - virtual void Unregister(); - // Control message handlers. void OnPageContents(const GURL& url, int32 page_id, const std::wstring& contents); diff --git a/chrome/browser/renderer_host/render_process_host.cc b/chrome/browser/renderer_host/render_process_host.cc index ad44ac8..8cafe1e 100644 --- a/chrome/browser/renderer_host/render_process_host.cc +++ b/chrome/browser/renderer_host/render_process_host.cc @@ -52,8 +52,6 @@ unsigned int GetMaxRendererProcessCount() { // Returns true if the given host is suitable for launching a new view // associated with the given profile. -// TODO(jabdelmalek): do we want to avoid processes with hung renderers -// or with a large memory consumption? static bool IsSuitableHost(Profile* profile, RenderProcessHost* host) { return host->profile() == profile; } @@ -68,8 +66,8 @@ bool RenderProcessHost::run_renderer_in_process_ = false; RenderProcessHost::RenderProcessHost(Profile* profile) : max_page_id_(-1), notified_termination_(false), + pid_(-1), profile_(profile) { - host_id_ = all_hosts.Add(this); } RenderProcessHost::~RenderProcessHost() { @@ -97,7 +95,10 @@ void RenderProcessHost::Release(int listener_id) { Details<bool>(&close_expected)); notified_termination_ = true; } - Unregister(); + if (pid_ >= 0) { + all_hosts.Remove(pid_); + pid_ = -1; + } MessageLoop::current()->DeleteSoon(FROM_HERE, this); } } @@ -167,9 +168,12 @@ RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile) { return NULL; } -void RenderProcessHost::Unregister() { - if (host_id_ >= 0) { - all_hosts.Remove(host_id_); - host_id_ = -1; +void RenderProcessHost::SetProcessID(int pid) { + if (pid_ != -1) { + // This object is being reused after a renderer crash. Remove the old pid. + all_hosts.Remove(pid_); } + + pid_ = pid; + all_hosts.AddWithID(this, pid); } diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h index 4f8179c..6e59166 100644 --- a/chrome/browser/renderer_host/render_process_host.h +++ b/chrome/browser/renderer_host/render_process_host.h @@ -33,10 +33,10 @@ class RenderProcessHost : public IPC::Channel::Sender, // Returns the user profile associated with this renderer process. Profile* profile() const { return profile_; } - // Returns the unique identifier for this host. This can be used later in + // Returns the process id for this host. This can be used later in // a call to FromID() to get back to this object (this is used to avoid // sending non-threadsafe pointers to other threads). - int host_id() const { return host_id_; } + int pid() const { return pid_; } // Returns the process object associated with the child process. In certain // tests or single-process mode, this will actually represent the current @@ -172,13 +172,8 @@ class RenderProcessHost : public IPC::Channel::Sender, static RenderProcessHost* GetExistingProcessHost(Profile* profile); protected: - // Unregister this object from all globals that reference it. - // This would naturally be part of the destructor, but we destruct - // asynchronously. - // - // This can be overridden by derived classes to add their own unregister code, - // but you should be sure to always call this one AT THE END of your own. - virtual void Unregister(); + // Sets the process of this object, so that others access it using FromID. + void SetProcessID(int pid); base::Process process_; @@ -198,7 +193,7 @@ class RenderProcessHost : public IPC::Channel::Sender, bool notified_termination_; private: - int host_id_; + int pid_; Profile* profile_; diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 155f6a3..734fd6d 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -121,7 +121,7 @@ RenderViewHost::~RenderViewHost() { // Be sure to clean up any leftover state from cross-site requests. Singleton<CrossSiteRequestManager>()->SetHasPendingCrossSiteRequest( - process()->host_id(), routing_id(), false); + process()->pid(), routing_id(), false); NotificationService::current()->Notify( NotificationType::RENDER_VIEW_HOST_DELETED, @@ -141,6 +141,11 @@ bool RenderViewHost::CreateRenderView() { DCHECK(process()->channel()); DCHECK(process()->profile()); + if (enabled_bindings_ & BindingsPolicy::DOM_UI) { + RendererSecurityPolicy::GetInstance()->GrantDOMUIBindings( + process()->pid()); + } + renderer_initialized_ = true; #if defined(OS_WIN) @@ -201,7 +206,7 @@ void RenderViewHost::NavigateToEntry(const NavigationEntry& entry, MakeNavigateParams(entry, is_reload, ¶ms); RendererSecurityPolicy::GetInstance()->GrantRequestURL( - process()->host_id(), params.url); + process()->pid(), params.url); DoNavigate(new ViewMsg_Navigate(routing_id(), params)); } @@ -214,7 +219,7 @@ void RenderViewHost::NavigateToURL(const GURL& url) { params.reload = false; RendererSecurityPolicy::GetInstance()->GrantRequestURL( - process()->host_id(), params.url); + process()->pid(), params.url); DoNavigate(new ViewMsg_Navigate(routing_id(), params)); } @@ -276,8 +281,7 @@ void RenderViewHost::FirePageBeforeUnload() { } void RenderViewHost::FirePageUnload() { - ClosePage(site_instance()->process_host_id(), - routing_id()); + ClosePage(process()->pid(), routing_id()); } // static @@ -317,7 +321,7 @@ void RenderViewHost::ClosePage(int new_render_process_host_id, void RenderViewHost::SetHasPendingCrossSiteRequest(bool has_pending_request, int request_id) { Singleton<CrossSiteRequestManager>()->SetHasPendingCrossSiteRequest( - process()->host_id(), routing_id(), has_pending_request); + process()->pid(), routing_id(), has_pending_request); pending_request_id_ = request_id; } @@ -387,13 +391,12 @@ void RenderViewHost::DragTargetDragEnter(const WebDropData& drop_data, const gfx::Point& client_pt, const gfx::Point& screen_pt) { // Grant the renderer the ability to load the drop_data. RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); - policy->GrantRequestURL(process()->host_id(), drop_data.url); + policy->GrantRequestURL(process()->pid(), drop_data.url); for (std::vector<std::wstring>::const_iterator iter(drop_data.filenames.begin()); iter != drop_data.filenames.end(); ++iter) { - policy->GrantRequestURL(process()->host_id(), - net::FilePathToFileURL(*iter)); - policy->GrantUploadFile(process()->host_id(), *iter); + policy->GrantRequestURL(process()->pid(), net::FilePathToFileURL(*iter)); + policy->GrantUploadFile(process()->pid(), *iter); } Send(new ViewMsg_DragTargetDragEnter(routing_id(), drop_data, client_pt, screen_pt)); @@ -544,14 +547,12 @@ void RenderViewHost::CopyImageAt(int x, int y) { } void RenderViewHost::InspectElementAt(int x, int y) { - RendererSecurityPolicy::GetInstance()->GrantInspectElement( - process()->host_id()); + RendererSecurityPolicy::GetInstance()->GrantInspectElement(process()->pid()); Send(new ViewMsg_InspectElement(routing_id(), x, y)); } void RenderViewHost::ShowJavaScriptConsole() { - RendererSecurityPolicy::GetInstance()->GrantInspectElement( - process()->host_id()); + RendererSecurityPolicy::GetInstance()->GrantInspectElement(process()->pid()); Send(new ViewMsg_ShowJavaScriptConsole(routing_id())); } @@ -585,8 +586,6 @@ void RenderViewHost::AllowExternalHostBindings() { void RenderViewHost::AllowDOMUIBindings() { DCHECK(!renderer_initialized_); enabled_bindings_ |= BindingsPolicy::DOM_UI; - RendererSecurityPolicy::GetInstance()->GrantDOMUIBindings( - process()->host_id()); } void RenderViewHost::AllowExtensionBindings() { @@ -629,7 +628,7 @@ void RenderViewHost::InstallMissingPlugin() { } void RenderViewHost::FileSelected(const std::wstring& path) { - RendererSecurityPolicy::GetInstance()->GrantUploadFile(process()->host_id(), + RendererSecurityPolicy::GetInstance()->GrantUploadFile(process()->pid(), path); std::vector<std::wstring> files; files.push_back(path); @@ -641,7 +640,7 @@ void RenderViewHost::MultiFilesSelected( for (std::vector<std::wstring>::const_iterator file = files.begin(); file != files.end(); ++file) { RendererSecurityPolicy::GetInstance()->GrantUploadFile( - process()->host_id(), *file); + process()->pid(), *file); } Send(new ViewMsg_RunFileChooserResponse(routing_id(), files)); } @@ -864,7 +863,7 @@ void RenderViewHost::OnMsgNavigate(const IPC::Message& msg) { Read(&msg, &iter, &validated_params)) return; - const int renderer_id = process()->host_id(); + const int renderer_id = process()->pid(); RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); // Without this check, an evil renderer can trick the browser into creating // a navigation entry for a banned URL. If the user clicks the back button @@ -953,7 +952,7 @@ void RenderViewHost::OnMsgDidStartProvisionalLoadForFrame(bool is_main_frame, const GURL& url) { GURL validated_url(url); FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); + process()->pid(), &validated_url); delegate_->DidStartProvisionalLoadForFrame(this, is_main_frame, validated_url); @@ -966,7 +965,7 @@ void RenderViewHost::OnMsgDidFailProvisionalLoadWithError( bool showing_repost_interstitial) { GURL validated_url(url); FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); + process()->pid(), &validated_url); delegate_->DidFailProvisionalLoadWithError(this, is_main_frame, error_code, validated_url, @@ -1011,7 +1010,7 @@ void RenderViewHost::OnMsgContextMenu(const ContextMenuParams& params) { // Validate the URLs in |params|. If the renderer can't request the URLs // directly, don't show them in the context menu. ContextMenuParams validated_params(params); - const int renderer_id = process()->host_id(); + const int renderer_id = process()->pid(); RendererSecurityPolicy* policy = RendererSecurityPolicy::GetInstance(); FilterURL(policy, renderer_id, &validated_params.link_url); @@ -1027,7 +1026,7 @@ void RenderViewHost::OnMsgOpenURL(const GURL& url, WindowOpenDisposition disposition) { GURL validated_url(url); FilterURL(RendererSecurityPolicy::GetInstance(), - process()->host_id(), &validated_url); + process()->pid(), &validated_url); delegate_->RequestOpenURL(validated_url, referrer, disposition); } @@ -1040,7 +1039,7 @@ void RenderViewHost::OnMsgDomOperationResponse( void RenderViewHost::OnMsgDOMUISend( const std::string& message, const std::string& content) { if (!RendererSecurityPolicy::GetInstance()-> - HasDOMUIBindings(process()->host_id())) { + HasDOMUIBindings(process()->pid())) { NOTREACHED() << "Blocked unauthorized use of DOMUIBindings."; return; } diff --git a/chrome/browser/renderer_host/render_widget_helper.cc b/chrome/browser/renderer_host/render_widget_helper.cc index 561ef18..9cf1172 100644 --- a/chrome/browser/renderer_host/render_widget_helper.cc +++ b/chrome/browser/renderer_host/render_widget_helper.cc @@ -41,9 +41,8 @@ class RenderWidgetHelper::PaintMsgProxy : public Task { DISALLOW_COPY_AND_ASSIGN(PaintMsgProxy); }; -RenderWidgetHelper::RenderWidgetHelper( - int render_process_id, ResourceDispatcherHost* resource_dispatcher_host) - : render_process_id_(render_process_id), +RenderWidgetHelper::RenderWidgetHelper() + : render_process_id_(-1), ui_loop_(MessageLoop::current()), #if defined(OS_WIN) event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), @@ -51,7 +50,7 @@ RenderWidgetHelper::RenderWidgetHelper( event_(false /* auto-reset */, false), #endif block_popups_(false), - resource_dispatcher_host_(resource_dispatcher_host) { + resource_dispatcher_host_(NULL) { } RenderWidgetHelper::~RenderWidgetHelper() { @@ -64,12 +63,19 @@ RenderWidgetHelper::~RenderWidgetHelper() { #endif } +void RenderWidgetHelper::Init( + int render_process_id, + ResourceDispatcherHost* resource_dispatcher_host) { + render_process_id_ = render_process_id; + resource_dispatcher_host_ = resource_dispatcher_host; +} + int RenderWidgetHelper::GetNextRoutingID() { return next_routing_id_.GetNext() + 1; } void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) { - if (g_browser_process->io_thread()) { + if (g_browser_process->io_thread() && render_process_id_ != -1) { g_browser_process->io_thread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(this, &RenderWidgetHelper::OnCancelResourceRequests, diff --git a/chrome/browser/renderer_host/render_widget_helper.h b/chrome/browser/renderer_host/render_widget_helper.h index a3aa321..193a09c 100644 --- a/chrome/browser/renderer_host/render_widget_helper.h +++ b/chrome/browser/renderer_host/render_widget_helper.h @@ -86,10 +86,12 @@ class ResourceDispatcherHost; class RenderWidgetHelper : public base::RefCountedThreadSafe<RenderWidgetHelper> { public: - RenderWidgetHelper(int render_process_id, - ResourceDispatcherHost* resource_dispatcher_host); + RenderWidgetHelper(); ~RenderWidgetHelper(); + void Init(int render_process_id, + ResourceDispatcherHost* resource_dispatcher_host); + // Gets the next available routing id. This is thread safe. int GetNextRoutingID(); diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc index 9783936..02ae30a 100644 --- a/chrome/browser/renderer_host/resource_message_filter.cc +++ b/chrome/browser/renderer_host/resource_message_filter.cc @@ -56,21 +56,21 @@ namespace { class ContextMenuMessageDispatcher : public Task { public: ContextMenuMessageDispatcher( - int render_process_host_id, + int render_process_id, const ViewHostMsg_ContextMenu& context_menu_message) - : render_process_host_id_(render_process_host_id), + : render_process_id_(render_process_id), context_menu_message_(context_menu_message) { } void Run() { RenderProcessHost* host = - RenderProcessHost::FromID(render_process_host_id_); + RenderProcessHost::FromID(render_process_id_); if (host) host->OnMessageReceived(context_menu_message_); } private: - int render_process_host_id_; + int render_process_id_; const ViewHostMsg_ContextMenu context_menu_message_; DISALLOW_COPY_AND_ASSIGN(ContextMenuMessageDispatcher); @@ -102,7 +102,6 @@ ResourceMessageFilter::ResourceMessageFilter( AudioRendererHost* audio_renderer_host, PluginService* plugin_service, printing::PrintJobManager* print_job_manager, - int render_process_host_id, Profile* profile, RenderWidgetHelper* render_widget_helper, SpellChecker* spellchecker) @@ -110,7 +109,7 @@ ResourceMessageFilter::ResourceMessageFilter( resource_dispatcher_host_(resource_dispatcher_host), plugin_service_(plugin_service), print_job_manager_(print_job_manager), - render_process_host_id_(render_process_host_id), + render_process_id_(-1), spellchecker_(spellchecker), ALLOW_THIS_IN_INITIALIZER_LIST(resolve_proxy_msg_helper_(this, NULL)), render_handle_(NULL), @@ -138,6 +137,11 @@ ResourceMessageFilter::~ResourceMessageFilter() { Source<Profile>(static_cast<Profile*>(profile_))); } +void ResourceMessageFilter::Init(int render_process_id) { + render_process_id_ = render_process_id; + render_widget_helper_->Init(render_process_id, resource_dispatcher_host_); +} + // Called on the IPC thread: void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) { channel_ = channel; @@ -165,7 +169,7 @@ void ResourceMessageFilter::OnChannelClosing() { // Unhook us from all pending network requests so they don't get sent to a // deleted object. - resource_dispatcher_host_->CancelRequestsForProcess(render_process_host_id_); + resource_dispatcher_host_->CancelRequestsForProcess(render_process_id_); // Unhook AudioRendererHost. audio_renderer_host_->IPCChannelClosing(); @@ -295,7 +299,7 @@ void ResourceMessageFilter::OnReceiveContextMenuMsg(const IPC::Message& msg) { // Create a new ViewHostMsg_ContextMenu message. const ViewHostMsg_ContextMenu context_menu_message(msg.routing_id(), params); render_widget_helper_->ui_loop()->PostTask(FROM_HERE, - new ContextMenuMessageDispatcher(render_process_host_id_, + new ContextMenuMessageDispatcher(render_process_id_, context_menu_message)); } @@ -332,7 +336,7 @@ void ResourceMessageFilter::OnRequestResource( resource_dispatcher_host_->BeginRequest(this, ChildProcessInfo::RENDER_PROCESS, render_handle_, - render_process_host_id_, + render_process_id_, message.routing_id(), request_id, request, @@ -341,17 +345,16 @@ void ResourceMessageFilter::OnRequestResource( } void ResourceMessageFilter::OnDataReceivedACK(int request_id) { - resource_dispatcher_host_->OnDataReceivedACK(render_process_host_id_, - request_id); + resource_dispatcher_host_->OnDataReceivedACK(render_process_id_, request_id); } void ResourceMessageFilter::OnUploadProgressACK(int request_id) { - resource_dispatcher_host_->OnUploadProgressACK(render_process_host_id_, + resource_dispatcher_host_->OnUploadProgressACK(render_process_id_, request_id); } void ResourceMessageFilter::OnCancelRequest(int request_id) { - resource_dispatcher_host_->CancelRequest(render_process_host_id_, request_id, + resource_dispatcher_host_->CancelRequest(render_process_id_, request_id, true); } @@ -368,7 +371,7 @@ void ResourceMessageFilter::OnSyncLoad( resource_dispatcher_host_->BeginRequest(this, ChildProcessInfo::RENDER_PROCESS, render_handle_, - render_process_host_id_, + render_process_id_, sync_result->routing_id(), request_id, request, @@ -516,7 +519,7 @@ void ResourceMessageFilter::OnDownloadUrl(const IPC::Message& message, const GURL& referrer) { resource_dispatcher_host_->BeginDownload(url, referrer, - render_process_host_id_, + render_process_id_, message.routing_id(), request_context_); } diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h index 55ce1be..10a12ed 100644 --- a/chrome/browser/renderer_host/resource_message_filter.h +++ b/chrome/browser/renderer_host/resource_message_filter.h @@ -68,12 +68,13 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, AudioRendererHost* audio_renderer_host, PluginService* plugin_service, printing::PrintJobManager* print_job_manager, - int render_process_host_id, Profile* profile, RenderWidgetHelper* render_widget_helper, SpellChecker* spellchecker); virtual ~ResourceMessageFilter(); + void Init(int render_process_id); + // IPC::ChannelProxy::MessageFilter methods: virtual void OnFilterAdded(IPC::Channel* channel); virtual void OnChannelConnected(int32 peer_pid); @@ -86,10 +87,6 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // Access to the spell checker. SpellChecker* spellchecker() { return spellchecker_.get(); } - int render_process_host_id() const { return render_process_host_id_;} - - base::ProcessHandle renderer_handle() const { return render_handle_;} - // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, @@ -239,7 +236,7 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter, // used by the ResourceDispatcherHost to look up the TabContents that // originated URLRequest. Since the RenderProcessHost can be destroyed // before this object, we only hold an ID for lookup. - int render_process_host_id_; + int render_process_id_; // Our spellchecker object. scoped_refptr<SpellChecker> spellchecker_; diff --git a/chrome/browser/site_instance_unittest.cc b/chrome/browser/site_instance_unittest.cc index 2001d53..d9e64ee 100644 --- a/chrome/browser/site_instance_unittest.cc +++ b/chrome/browser/site_instance_unittest.cc @@ -177,16 +177,15 @@ TEST_F(SiteInstanceTest, UpdateMaxPageID) { // Test to ensure GetProcess returns and creates processes correctly. TEST_F(SiteInstanceTest, GetProcess) { - // Ensure that GetProcess returns the process based on its host id. + // Ensure that GetProcess returns a process. scoped_ptr<TestingProfile> profile(new TestingProfile()); - scoped_ptr<BrowserRenderProcessHost> host1( - new BrowserRenderProcessHost(profile.get())); + scoped_ptr<RenderProcessHost> host1; scoped_refptr<SiteInstance> instance( SiteInstance::CreateSiteInstance(profile.get())); - instance.get()->set_process_host_id(host1.get()->host_id()); - EXPECT_EQ(host1.get(), instance.get()->GetProcess()); + host1.reset(instance.get()->GetProcess()); + EXPECT_TRUE(host1.get() != NULL); - // Ensure that GetProcess creates a new process if no host id is set. + // Ensure that GetProcess creates a new process. scoped_refptr<SiteInstance> instance2( SiteInstance::CreateSiteInstance(profile.get())); scoped_ptr<RenderProcessHost> host2(instance2.get()->GetProcess()); diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc index 91b1373..f6373c7 100644 --- a/chrome/browser/ssl/ssl_blocking_page.cc +++ b/chrome/browser/ssl/ssl_blocking_page.cc @@ -74,7 +74,7 @@ void SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { WebContents* web = tab()->AsWebContents(); const net::SSLInfo& ssl_info = error_->ssl_info(); int cert_id = CertStore::GetSharedInstance()->StoreCert( - ssl_info.cert, web->render_view_host()->process()->host_id()); + ssl_info.cert, web->render_view_host()->process()->pid()); entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); entry->ssl().set_cert_id(cert_id); diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc index 4a0fdef..1748639 100644 --- a/chrome/browser/ssl/ssl_policy.cc +++ b/chrome/browser/ssl/ssl_policy.cc @@ -98,7 +98,7 @@ static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) { WebContents* tab = error->GetWebContents(); int cert_id = CertStore::GetSharedInstance()->StoreCert( - error->ssl_info().cert, tab->render_view_host()->process()->host_id()); + error->ssl_info().cert, tab->render_view_host()->process()->pid()); std::string security_info = SSLManager::SerializeSecurityInfo(cert_id, error->ssl_info().cert_status, diff --git a/chrome/browser/tab_contents/interstitial_page.cc b/chrome/browser/tab_contents/interstitial_page.cc index 4d56420..a4e4f5b 100644 --- a/chrome/browser/tab_contents/interstitial_page.cc +++ b/chrome/browser/tab_contents/interstitial_page.cc @@ -110,7 +110,7 @@ InterstitialPage::InterstitialPage(WebContents* tab, enabled_(true), action_taken_(false), render_view_host_(NULL), - original_rvh_process_id_(tab->render_view_host()->process()->host_id()), + original_rvh_process_id_(tab->render_view_host()->process()->pid()), original_rvh_id_(tab->render_view_host()->routing_id()), should_revert_tab_title_(false), resource_dispatcher_host_notified_(false), @@ -217,7 +217,7 @@ void InterstitialPage::Observe(NotificationType type, // The RenderViewHost is being destroyed (as part of the tab being // closed), make sure we clear the blocked requests. RenderViewHost* rvh = Source<RenderViewHost>(source).ptr(); - DCHECK(rvh->process()->host_id() == original_rvh_process_id_ && + DCHECK(rvh->process()->pid() == original_rvh_process_id_ && rvh->routing_id() == original_rvh_id_); TakeActionOnResourceDispatcher(CANCEL); } diff --git a/chrome/browser/tab_contents/render_view_host_manager.cc b/chrome/browser/tab_contents/render_view_host_manager.cc index 162ecb9..715f2bf 100644 --- a/chrome/browser/tab_contents/render_view_host_manager.cc +++ b/chrome/browser/tab_contents/render_view_host_manager.cc @@ -148,8 +148,7 @@ bool RenderViewHostManager::ShouldCloseTabOnUnresponsiveRenderer() { // handler later finishes, this call will be ignored because the state in // CrossSiteResourceHandler will already be cleaned up.) current_host()->process()->CrossSiteClosePageACK( - pending_render_view_host_->site_instance()->process_host_id(), - pending_request_id); + pending_render_view_host_->process()->pid(), pending_request_id); } return false; } diff --git a/chrome/browser/tab_contents/site_instance.cc b/chrome/browser/tab_contents/site_instance.cc index 6582be6..05b3fbd 100644 --- a/chrome/browser/tab_contents/site_instance.cc +++ b/chrome/browser/tab_contents/site_instance.cc @@ -6,48 +6,58 @@ #include "chrome/browser/renderer_host/browser_render_process_host.h" #include "chrome/common/url_constants.h" +#include "chrome/common/notification_service.h" #include "net/base/registry_controlled_domain.h" +SiteInstance::SiteInstance(BrowsingInstance* browsing_instance) + : browsing_instance_(browsing_instance), + render_process_host_factory_(NULL), + process_(NULL), + max_page_id_(-1), + has_site_(false) { + DCHECK(browsing_instance); + + NotificationService::current()->AddObserver(this, + NotificationType::RENDERER_PROCESS_TERMINATED, + NotificationService::AllSources()); +} + SiteInstance::~SiteInstance() { // Now that no one is referencing us, we can safely remove ourselves from // the BrowsingInstance. Any future visits to a page from this site // (within the same BrowsingInstance) can safely create a new SiteInstance. if (has_site_) browsing_instance_->UnregisterSiteInstance(this); + + NotificationService::current()->RemoveObserver(this, + NotificationType::RENDERER_PROCESS_TERMINATED, + NotificationService::AllSources()); } RenderProcessHost* SiteInstance::GetProcess() { - RenderProcessHost* process = NULL; - if (process_host_id_ != -1) - process = RenderProcessHost::FromID(process_host_id_); - // Create a new process if ours went away or was reused. - if (!process) { + if (!process_) { // See if we should reuse an old process if (RenderProcessHost::ShouldTryToUseExistingProcessHost()) - process = RenderProcessHost::GetExistingProcessHost( + process_ = RenderProcessHost::GetExistingProcessHost( browsing_instance_->profile()); // Otherwise (or if that fails), create a new one. - if (!process) { + if (!process_) { if (render_process_host_factory_) { - process = render_process_host_factory_->CreateRenderProcessHost( + process_ = render_process_host_factory_->CreateRenderProcessHost( browsing_instance_->profile()); } else { - process = new BrowserRenderProcessHost(browsing_instance_->profile()); + process_ = new BrowserRenderProcessHost(browsing_instance_->profile()); } } - // Update our host ID, so all pages in this SiteInstance will use - // the correct process. - process_host_id_ = process->host_id(); - // Make sure the process starts at the right max_page_id - process->UpdateMaxPageID(max_page_id_); + process_->UpdateMaxPageID(max_page_id_); } - DCHECK(process); + DCHECK(process_); - return process; + return process_; } void SiteInstance::SetSite(const GURL& url) { @@ -151,3 +161,12 @@ bool SiteInstance::IsSameWebSite(const GURL& url1, const GURL& url2) { return net::RegistryControlledDomainService::SameDomainOrHost(url1, url2); } + +void SiteInstance::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::RENDERER_PROCESS_TERMINATED); + RenderProcessHost* rph = Source<RenderProcessHost>(source).ptr(); + if (rph == process_) + process_ = NULL; +} diff --git a/chrome/browser/tab_contents/site_instance.h b/chrome/browser/tab_contents/site_instance.h index 6e25a2b..34cef93 100644 --- a/chrome/browser/tab_contents/site_instance.h +++ b/chrome/browser/tab_contents/site_instance.h @@ -7,6 +7,7 @@ #include "chrome/browser/browsing_instance.h" #include "chrome/browser/renderer_host/render_process_host.h" +#include "chrome/common/notification_observer.h" #include "googleurl/src/gurl.h" /////////////////////////////////////////////////////////////////////////////// @@ -43,7 +44,8 @@ // tabs with no NavigationEntries or in NavigationEntries in the history. // /////////////////////////////////////////////////////////////////////////////// -class SiteInstance : public base::RefCounted<SiteInstance> { +class SiteInstance : public base::RefCounted<SiteInstance>, + public NotificationObserver { public: // Virtual to allow tests to extend it. virtual ~SiteInstance(); @@ -61,12 +63,6 @@ class SiteInstance : public base::RefCounted<SiteInstance> { render_process_host_factory_ = rph_factory; } - // Set / Get the host ID for this SiteInstance's current RenderProcessHost. - void set_process_host_id(int process_host_id) { - process_host_id_ = process_host_id; - } - int process_host_id() const { return process_host_id_; } - // Update / Get the max page ID for this SiteInstance. void UpdateMaxPageID(int32 page_id) { if (page_id > max_page_id_) @@ -133,16 +129,14 @@ class SiteInstance : public base::RefCounted<SiteInstance> { // Create a new SiteInstance. Protected to give access to BrowsingInstance // and tests; most callers should use CreateSiteInstance or // GetRelatedSiteInstance instead. - SiteInstance(BrowsingInstance* browsing_instance) - : browsing_instance_(browsing_instance), - render_process_host_factory_(NULL), - process_host_id_(-1), - max_page_id_(-1), - has_site_(false) { - DCHECK(browsing_instance); - } + SiteInstance(BrowsingInstance* browsing_instance); private: + // NotificationObserver implementation. + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // BrowsingInstance to which this SiteInstance belongs. scoped_refptr<BrowsingInstance> browsing_instance_; @@ -150,11 +144,8 @@ class SiteInstance : public base::RefCounted<SiteInstance> { // that the default BrowserRenderProcessHost should be created. const RenderProcessHostFactory* render_process_host_factory_; - // Current host ID for the RenderProcessHost that is rendering pages for this - // SiteInstance. If the rendering process dies, this host ID can be - // replaced when a new process is created, without losing the association - // between all pages in this SiteInstance. - int process_host_id_; + // Current RenderProcessHost that is rendering pages for this SiteInstance. + RenderProcessHost* process_; // The current max_page_id in the SiteInstance's RenderProcessHost. If the // rendering process dies, its replacement should start issuing page IDs that diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc index 8f1a5ea..5b935b5 100644 --- a/chrome/browser/tab_contents/web_contents.cc +++ b/chrome/browser/tab_contents/web_contents.cc @@ -438,7 +438,10 @@ void WebContents::DidBecomeSelected() { if (render_widget_host_view()) render_widget_host_view()->DidBecomeSelected(); - CacheManagerHost::GetInstance()->ObserveActivity(process()->host_id()); + // If pid() is -1, that means the RenderProcessHost still hasn't been + // initialized. It'll register with CacheManagerHost when it is. + if (process()->pid() != -1) + CacheManagerHost::GetInstance()->ObserveActivity(process()->pid()); } void WebContents::WasHidden() { diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc index 51a9ffb..c1842cd 100644 --- a/chrome/browser/tab_contents/web_contents_view_win.cc +++ b/chrome/browser/tab_contents/web_contents_view_win.cc @@ -232,7 +232,7 @@ void WebContentsViewWin::OpenDeveloperTools() { if (!host) return; - dev_tools_window_->Show(host->process()->host_id(), host->routing_id()); + dev_tools_window_->Show(host->process()->pid(), host->routing_id()); } void WebContentsViewWin::ForwardMessageToDevToolsClient( |