Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: chrome/browser/renderer_host/render_process_host.cc

Issue 6532073: Move core pieces of browser\renderer_host to src\content. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/renderer_host/render_process_host.h"
6
7 #include "base/rand_util.h"
8 #include "base/sys_info.h"
9 #include "chrome/browser/child_process_security_policy.h"
10 #include "chrome/common/child_process_info.h"
11 #include "chrome/common/chrome_constants.h"
12 #include "chrome/common/notification_service.h"
13
14 namespace {
15
16 size_t max_renderer_count_override = 0;
17
18 size_t GetMaxRendererProcessCount() {
19 if (max_renderer_count_override)
20 return max_renderer_count_override;
21
22 // Defines the maximum number of renderer processes according to the
23 // amount of installed memory as reported by the OS. The table
24 // values are calculated by assuming that you want the renderers to
25 // use half of the installed ram and assuming that each tab uses
26 // ~40MB, however the curve is not linear but piecewise linear with
27 // interleaved slopes of 3 and 2.
28 // If you modify this table you need to adjust browser\browser_uitest.cc
29 // to match the expected number of processes.
30
31 static const size_t kMaxRenderersByRamTier[] = {
32 3, // less than 256MB
33 6, // 256MB
34 9, // 512MB
35 12, // 768MB
36 14, // 1024MB
37 18, // 1280MB
38 20, // 1536MB
39 22, // 1792MB
40 24, // 2048MB
41 26, // 2304MB
42 29, // 2560MB
43 32, // 2816MB
44 35, // 3072MB
45 38, // 3328MB
46 40 // 3584MB
47 };
48
49 static size_t max_count = 0;
50 if (!max_count) {
51 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256;
52 if (memory_tier >= arraysize(kMaxRenderersByRamTier))
53 max_count = chrome::kMaxRendererProcessCount;
54 else
55 max_count = kMaxRenderersByRamTier[memory_tier];
56 }
57 return max_count;
58 }
59
60 // Returns true if the given host is suitable for launching a new view
61 // associated with the given profile.
62 static bool IsSuitableHost(RenderProcessHost* host, Profile* profile,
63 RenderProcessHost::Type type) {
64 if (host->profile() != profile)
65 return false;
66
67 RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL;
68 if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()))
69 host_type = RenderProcessHost::TYPE_WEBUI;
70 if (ChildProcessSecurityPolicy::GetInstance()->
71 HasExtensionBindings(host->id()))
72 host_type = RenderProcessHost::TYPE_EXTENSION;
73
74 return host_type == type;
75 }
76
77 // the global list of all renderer processes
78 IDMap<RenderProcessHost> all_hosts;
79
80 } // namespace
81
82 extern bool g_log_bug53991;
83
84 // static
85 bool RenderProcessHost::run_renderer_in_process_ = false;
86
87 // static
88 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
89 max_renderer_count_override = count;
90 }
91
92 RenderProcessHost::RenderProcessHost(Profile* profile)
93 : max_page_id_(-1),
94 fast_shutdown_started_(false),
95 deleting_soon_(false),
96 id_(ChildProcessInfo::GenerateChildProcessUniqueId()),
97 profile_(profile),
98 sudden_termination_allowed_(true),
99 ignore_input_events_(false) {
100 all_hosts.AddWithID(this, id());
101 all_hosts.set_check_on_null_data(true);
102 // Initialize |child_process_activity_time_| to a reasonable value.
103 mark_child_process_activity_time();
104 }
105
106 RenderProcessHost::~RenderProcessHost() {
107 // In unit tests, Release() might not have been called.
108 if (all_hosts.Lookup(id()))
109 all_hosts.Remove(id());
110 }
111
112 void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
113 int routing_id) {
114 VLOG_IF(1, g_log_bug53991) << "AddListener: (" << this << "): " << routing_id;
115 listeners_.AddWithID(listener, routing_id);
116 }
117
118 void RenderProcessHost::Release(int listener_id) {
119 VLOG_IF(1, g_log_bug53991) << "RemListener: (" << this << "): "
120 << listener_id;
121 DCHECK(listeners_.Lookup(listener_id) != NULL);
122 listeners_.Remove(listener_id);
123
124 // Make sure that all associated resource requests are stopped.
125 CancelResourceRequests(listener_id);
126
127 // When no other owners of this object, we can delete ourselves
128 if (listeners_.IsEmpty()) {
129 NotificationService::current()->Notify(
130 NotificationType::RENDERER_PROCESS_TERMINATED,
131 Source<RenderProcessHost>(this), NotificationService::NoDetails());
132 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
133 deleting_soon_ = true;
134
135 // Remove ourself from the list of renderer processes so that we can't be
136 // reused in between now and when the Delete task runs.
137 all_hosts.Remove(id());
138 }
139 }
140
141 void RenderProcessHost::ReportExpectingClose(int32 listener_id) {
142 listeners_expecting_close_.insert(listener_id);
143 }
144
145 void RenderProcessHost::UpdateMaxPageID(int32 page_id) {
146 if (page_id > max_page_id_)
147 max_page_id_ = page_id;
148 }
149
150 bool RenderProcessHost::FastShutdownForPageCount(size_t count) {
151 if (listeners_.size() == count)
152 return FastShutdownIfPossible();
153 return false;
154 }
155
156 // static
157 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
158 return iterator(&all_hosts);
159 }
160
161 // static
162 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
163 return all_hosts.Lookup(render_process_id);
164 }
165
166 // static
167 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() {
168 size_t renderer_process_count = all_hosts.size();
169
170 // NOTE: Sometimes it's necessary to create more render processes than
171 // GetMaxRendererProcessCount(), for instance when we want to create
172 // a renderer process for a profile that has no existing renderers.
173 // This is OK in moderation, since the GetMaxRendererProcessCount()
174 // is conservative.
175
176 return run_renderer_in_process() ||
177 (renderer_process_count >= GetMaxRendererProcessCount());
178 }
179
180 // static
181 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile,
182 Type type) {
183 // First figure out which existing renderers we can use.
184 std::vector<RenderProcessHost*> suitable_renderers;
185 suitable_renderers.reserve(all_hosts.size());
186
187 iterator iter(AllHostsIterator());
188 while (!iter.IsAtEnd()) {
189 if (run_renderer_in_process() ||
190 IsSuitableHost(iter.GetCurrentValue(), profile, type))
191 suitable_renderers.push_back(iter.GetCurrentValue());
192
193 iter.Advance();
194 }
195
196 // Now pick a random suitable renderer, if we have any.
197 if (!suitable_renderers.empty()) {
198 int suitable_count = static_cast<int>(suitable_renderers.size());
199 int random_index = base::RandInt(0, suitable_count - 1);
200 return suitable_renderers[random_index];
201 }
202
203 return NULL;
204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698