diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 18:31:26 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-16 18:31:26 +0000 |
commit | 8c8657d61fb8792985888c88730b2eb2f4fc4019 (patch) | |
tree | 73f4290e22afe39a19d64a0792a5a2ff2740a32c /chrome/browser/renderer_host/render_process_host.cc | |
parent | 52ef74f432e2fb08be4f7ea323244884894fc656 (diff) | |
download | chromium_src-8c8657d61fb8792985888c88730b2eb2f4fc4019.zip chromium_src-8c8657d61fb8792985888c88730b2eb2f4fc4019.tar.gz chromium_src-8c8657d61fb8792985888c88730b2eb2f4fc4019.tar.bz2 |
Move functions required by the rest of the browser from RenderProcessHost to an interface and move the implementation to BrowserRenderProcessHost. This will allow me to write render view unit tests without using the actual renderer, but there are no tests yet.
Review URL: http://codereview.chromium.org/18132
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8188 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host/render_process_host.cc')
-rw-r--r-- | chrome/browser/renderer_host/render_process_host.cc | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/chrome/browser/renderer_host/render_process_host.cc b/chrome/browser/renderer_host/render_process_host.cc new file mode 100644 index 0000000..18323f4 --- /dev/null +++ b/chrome/browser/renderer_host/render_process_host.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2009 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 "chrome/browser/renderer_host/render_process_host.h" + +#include "base/rand_util.h" +#include "base/sys_info.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/notification_service.h" + +namespace { + +unsigned int GetMaxRendererProcessCount() { + // 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 ~25MB. + static const int kMaxRenderersByRamTier[] = { + 4, // less than 256MB + 8, // 256MB + 12, // 512MB + 16, // 768MB + }; + + static unsigned int max_count = 0; + if (!max_count) { + int memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; + if (memory_tier >= arraysize(kMaxRenderersByRamTier)) + max_count = chrome::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 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; +} + +// the global list of all renderer processes +IDMap<RenderProcessHost> all_hosts; + +} // namespace + +bool RenderProcessHost::run_renderer_in_process_ = false; + +RenderProcessHost::RenderProcessHost(Profile* profile) + : max_page_id_(-1), + notified_termination_(false), + profile_(profile) { + host_id_ = all_hosts.Add(this); +} + +RenderProcessHost::~RenderProcessHost() { +} + +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); + + // When no other owners of this object, we can delete ourselves + if (listeners_.IsEmpty()) { + if (!notified_termination_) { + bool close_expected = true; + NotificationService::current()->Notify( + NOTIFY_RENDERER_PROCESS_TERMINATED, + Source<RenderProcessHost>(this), + Details<bool>(&close_expected)); + notified_termination_ = true; + } + Unregister(); + MessageLoop::current()->DeleteSoon(FROM_HERE, this); + } +} + +void RenderProcessHost::ReportExpectingClose(int32 listener_id) { + listeners_expecting_close_.insert(listener_id); +} + +void RenderProcessHost::UpdateMaxPageID(int32 page_id) { + if (page_id > max_page_id_) + max_page_id_ = page_id; +} + +// static +RenderProcessHost::iterator RenderProcessHost::begin() { + return all_hosts.begin(); +} + +// static +RenderProcessHost::iterator RenderProcessHost::end() { + return all_hosts.end(); +} + +// static +size_t RenderProcessHost::size() { + return all_hosts.size(); +} + +// static +RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { + return all_hosts.Lookup(render_process_id); +} + +// static +bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { + unsigned int renderer_process_count = + static_cast<unsigned int>(all_hosts.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 profile 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(Profile* profile) { + // First figure out which existing renderers we can use. + std::vector<RenderProcessHost*> suitable_renderers; + suitable_renderers.reserve(size()); + + for (iterator iter = begin(); iter != end(); ++iter) { + if (IsSuitableHost(profile, iter->second)) + suitable_renderers.push_back(iter->second); + } + + // 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; +} + +void RenderProcessHost::Unregister() { + if (host_id_ >= 0) { + all_hosts.Remove(host_id_); + host_id_ = -1; + } +} |