| Index: content/browser/renderer_host/render_process_host.cc
|
| ===================================================================
|
| --- content/browser/renderer_host/render_process_host.cc (revision 110571)
|
| +++ content/browser/renderer_host/render_process_host.cc (working copy)
|
| @@ -1,251 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "content/browser/renderer_host/render_process_host.h"
|
| -
|
| -#include "base/command_line.h"
|
| -#include "base/lazy_instance.h"
|
| -#include "base/rand_util.h"
|
| -#include "base/sys_info.h"
|
| -#include "content/browser/browser_main.h"
|
| -#include "content/browser/child_process_security_policy.h"
|
| -#include "content/browser/webui/web_ui_factory.h"
|
| -#include "content/common/child_process_info.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/content_browser_client.h"
|
| -#include "content/public/browser/notification_service.h"
|
| -#include "content/public/browser/notification_types.h"
|
| -#include "content/public/common/content_constants.h"
|
| -#include "content/public/common/content_switches.h"
|
| -
|
| -using content::BrowserThread;
|
| -
|
| -namespace {
|
| -
|
| -size_t max_renderer_count_override = 0;
|
| -
|
| -size_t GetMaxRendererProcessCount() {
|
| - if (max_renderer_count_override)
|
| - return max_renderer_count_override;
|
| -
|
| - // Defines the maximum number of renderer processes according to the
|
| - // amount of installed memory as reported by the OS. The table
|
| - // values are calculated by assuming that you want the renderers to
|
| - // use half of the installed ram and assuming that each tab uses
|
| - // ~40MB, however the curve is not linear but piecewise linear with
|
| - // interleaved slopes of 3 and 2.
|
| - // If you modify this table you need to adjust browser\browser_uitest.cc
|
| - // to match the expected number of processes.
|
| -
|
| - static const size_t kMaxRenderersByRamTier[] = {
|
| - 3, // less than 256MB
|
| - 6, // 256MB
|
| - 9, // 512MB
|
| - 12, // 768MB
|
| - 14, // 1024MB
|
| - 18, // 1280MB
|
| - 20, // 1536MB
|
| - 22, // 1792MB
|
| - 24, // 2048MB
|
| - 26, // 2304MB
|
| - 29, // 2560MB
|
| - 32, // 2816MB
|
| - 35, // 3072MB
|
| - 38, // 3328MB
|
| - 40 // 3584MB
|
| - };
|
| -
|
| - static size_t max_count = 0;
|
| - if (!max_count) {
|
| - size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256;
|
| - if (memory_tier >= arraysize(kMaxRenderersByRamTier))
|
| - max_count = content::kMaxRendererProcessCount;
|
| - else
|
| - max_count = kMaxRenderersByRamTier[memory_tier];
|
| - }
|
| - return max_count;
|
| -}
|
| -
|
| -// Returns true if the given host is suitable for launching a new view
|
| -// associated with the given browser context.
|
| -static bool IsSuitableHost(RenderProcessHost* host,
|
| - content::BrowserContext* browser_context,
|
| - const GURL& site_url) {
|
| - if (host->browser_context() != browser_context)
|
| - return false;
|
| -
|
| - if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()) !=
|
| - content::WebUIFactory::Get()->HasWebUIScheme(site_url))
|
| - return false;
|
| -
|
| - return content::GetContentClient()->browser()->IsSuitableHost(host, site_url);
|
| -}
|
| -
|
| -// the global list of all renderer processes
|
| -base::LazyInstance<IDMap<RenderProcessHost>,
|
| - base::LeakyLazyInstanceTraits<IDMap<RenderProcessHost> > >
|
| - g_all_hosts = LAZY_INSTANCE_INITIALIZER;
|
| -
|
| -} // namespace
|
| -
|
| -// static
|
| -bool RenderProcessHost::run_renderer_in_process_ = false;
|
| -
|
| -// static
|
| -void RenderProcessHost::SetMaxRendererProcessCountForTest(size_t count) {
|
| - max_renderer_count_override = count;
|
| -}
|
| -
|
| -RenderProcessHost::RenderProcessHost(content::BrowserContext* browser_context)
|
| - : max_page_id_(-1),
|
| - fast_shutdown_started_(false),
|
| - deleting_soon_(false),
|
| - pending_views_(0),
|
| - id_(ChildProcessInfo::GenerateChildProcessUniqueId()),
|
| - browser_context_(browser_context),
|
| - sudden_termination_allowed_(true),
|
| - ignore_input_events_(false) {
|
| - CHECK(!content::ExitedMainMessageLoop());
|
| - g_all_hosts.Get().AddWithID(this, id());
|
| - g_all_hosts.Get().set_check_on_null_data(true);
|
| - // Initialize |child_process_activity_time_| to a reasonable value.
|
| - mark_child_process_activity_time();
|
| -}
|
| -
|
| -RenderProcessHost::~RenderProcessHost() {
|
| - // In unit tests, Release() might not have been called.
|
| - if (g_all_hosts.Get().Lookup(id()))
|
| - g_all_hosts.Get().Remove(id());
|
| -}
|
| -
|
| -bool RenderProcessHost::HasConnection() const {
|
| - return channel_.get() != NULL;
|
| -}
|
| -
|
| -void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
|
| - int routing_id) {
|
| - listeners_.AddWithID(listener, routing_id);
|
| -}
|
| -
|
| -void RenderProcessHost::Release(int listener_id) {
|
| - DCHECK(listeners_.Lookup(listener_id) != NULL);
|
| - listeners_.Remove(listener_id);
|
| -
|
| - // Make sure that all associated resource requests are stopped.
|
| - CancelResourceRequests(listener_id);
|
| -
|
| -#if defined(OS_WIN)
|
| - // Dump the handle table if handle auditing is enabled.
|
| - const CommandLine& browser_command_line =
|
| - *CommandLine::ForCurrentProcess();
|
| - if (browser_command_line.HasSwitch(switches::kAuditHandles) ||
|
| - browser_command_line.HasSwitch(switches::kAuditAllHandles)) {
|
| - DumpHandles();
|
| -
|
| - // We wait to close the channels until the child process has finished
|
| - // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone.
|
| - return;
|
| - }
|
| -#endif
|
| - Cleanup();
|
| -}
|
| -
|
| -void RenderProcessHost::Cleanup() {
|
| - // When no other owners of this object, we can delete ourselves
|
| - if (listeners_.IsEmpty()) {
|
| - content::NotificationService::current()->Notify(
|
| - content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
|
| - content::Source<RenderProcessHost>(this),
|
| - content::NotificationService::NoDetails());
|
| - MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| - deleting_soon_ = true;
|
| - // It's important not to wait for the DeleteTask to delete the channel
|
| - // proxy. Kill it off now. That way, in case the profile is going away, the
|
| - // rest of the objects attached to this RenderProcessHost start going
|
| - // away first, since deleting the channel proxy will post a
|
| - // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
|
| - channel_.reset();
|
| -
|
| - // Remove ourself from the list of renderer processes so that we can't be
|
| - // reused in between now and when the Delete task runs.
|
| - g_all_hosts.Get().Remove(id());
|
| - }
|
| -}
|
| -
|
| -void RenderProcessHost::ReportExpectingClose(int32 listener_id) {
|
| - listeners_expecting_close_.insert(listener_id);
|
| -}
|
| -
|
| -void RenderProcessHost::AddPendingView() {
|
| - pending_views_++;
|
| -}
|
| -
|
| -void RenderProcessHost::RemovePendingView() {
|
| - DCHECK(pending_views_);
|
| - pending_views_--;
|
| -}
|
| -
|
| -void RenderProcessHost::UpdateMaxPageID(int32 page_id) {
|
| - if (page_id > max_page_id_)
|
| - max_page_id_ = page_id;
|
| -}
|
| -
|
| -bool RenderProcessHost::FastShutdownForPageCount(size_t count) {
|
| - if (listeners_.size() == count)
|
| - return FastShutdownIfPossible();
|
| - return false;
|
| -}
|
| -
|
| -// static
|
| -RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - return iterator(g_all_hosts.Pointer());
|
| -}
|
| -
|
| -// static
|
| -RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
|
| - return g_all_hosts.Get().Lookup(render_process_id);
|
| -}
|
| -
|
| -// static
|
| -bool RenderProcessHost::ShouldTryToUseExistingProcessHost() {
|
| - size_t renderer_process_count = g_all_hosts.Get().size();
|
| -
|
| - // NOTE: Sometimes it's necessary to create more render processes than
|
| - // GetMaxRendererProcessCount(), for instance when we want to create
|
| - // a renderer process for a browser context that has no existing
|
| - // renderers. This is OK in moderation, since the
|
| - // GetMaxRendererProcessCount() is conservative.
|
| -
|
| - return run_renderer_in_process() ||
|
| - (renderer_process_count >= GetMaxRendererProcessCount());
|
| -}
|
| -
|
| -// static
|
| -RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
|
| - content::BrowserContext* browser_context,
|
| - const GURL& site_url) {
|
| - // First figure out which existing renderers we can use.
|
| - std::vector<RenderProcessHost*> suitable_renderers;
|
| - suitable_renderers.reserve(g_all_hosts.Get().size());
|
| -
|
| - iterator iter(AllHostsIterator());
|
| - while (!iter.IsAtEnd()) {
|
| - if (run_renderer_in_process() ||
|
| - IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url))
|
| - suitable_renderers.push_back(iter.GetCurrentValue());
|
| -
|
| - iter.Advance();
|
| - }
|
| -
|
| - // Now pick a random suitable renderer, if we have any.
|
| - if (!suitable_renderers.empty()) {
|
| - int suitable_count = static_cast<int>(suitable_renderers.size());
|
| - int random_index = base::RandInt(0, suitable_count - 1);
|
| - return suitable_renderers[random_index];
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
|
|