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

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

Issue 8515027: Define the public version of the browser side RenderProcessHost interface. This interface is not ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 "content/browser/renderer_host/render_process_host.h"
6
7 #include "base/command_line.h"
8 #include "base/lazy_instance.h"
9 #include "base/rand_util.h"
10 #include "base/sys_info.h"
11 #include "content/browser/browser_main.h"
12 #include "content/browser/child_process_security_policy.h"
13 #include "content/browser/webui/web_ui_factory.h"
14 #include "content/common/child_process_info.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/content_browser_client.h"
17 #include "content/public/browser/notification_service.h"
18 #include "content/public/browser/notification_types.h"
19 #include "content/public/common/content_constants.h"
20 #include "content/public/common/content_switches.h"
21
22 using content::BrowserThread;
23
24 namespace {
25
26 size_t max_renderer_count_override = 0;
27
28 size_t GetMaxRendererProcessCount() {
29 if (max_renderer_count_override)
30 return max_renderer_count_override;
31
32 // Defines the maximum number of renderer processes according to the
33 // amount of installed memory as reported by the OS. The table
34 // values are calculated by assuming that you want the renderers to
35 // use half of the installed ram and assuming that each tab uses
36 // ~40MB, however the curve is not linear but piecewise linear with
37 // interleaved slopes of 3 and 2.
38 // If you modify this table you need to adjust browser\browser_uitest.cc
39 // to match the expected number of processes.
40
41 static const size_t kMaxRenderersByRamTier[] = {
42 3, // less than 256MB
43 6, // 256MB
44 9, // 512MB
45 12, // 768MB
46 14, // 1024MB
47 18, // 1280MB
48 20, // 1536MB
49 22, // 1792MB
50 24, // 2048MB
51 26, // 2304MB
52 29, // 2560MB
53 32, // 2816MB
54 35, // 3072MB
55 38, // 3328MB
56 40 // 3584MB
57 };
58
59 static size_t max_count = 0;
60 if (!max_count) {
61 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256;
62 if (memory_tier >= arraysize(kMaxRenderersByRamTier))
63 max_count = content::kMaxRendererProcessCount;
64 else
65 max_count = kMaxRenderersByRamTier[memory_tier];
66 }
67 return max_count;
68 }
69
70 // Returns true if the given host is suitable for launching a new view
71 // associated with the given browser context.
72 static bool IsSuitableHost(RenderProcessHost* host,
73 content::BrowserContext* browser_context,
74 const GURL& site_url) {
75 if (host->browser_context() != browser_context)
76 return false;
77
78 if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()) !=
79 content::WebUIFactory::Get()->HasWebUIScheme(site_url))
80 return false;
81
82 return content::GetContentClient()->browser()->IsSuitableHost(host, site_url);
83 }
84
85 // the global list of all renderer processes
86 base::LazyInstance<IDMap<RenderProcessHost>,
87 base::LeakyLazyInstanceTraits<IDMap<RenderProcessHost> > >
88 g_all_hosts = LAZY_INSTANCE_INITIALIZER;
89
90 } // namespace
91
92 // static
93 bool RenderProcessHost::run_renderer_in_process_ = false;
94
95 // static
96 void RenderProcessHost::SetMaxRendererProcessCountForTest(size_t count) {
97 max_renderer_count_override = count;
98 }
99
100 RenderProcessHost::RenderProcessHost(content::BrowserContext* browser_context)
101 : max_page_id_(-1),
102 fast_shutdown_started_(false),
103 deleting_soon_(false),
104 pending_views_(0),
105 id_(ChildProcessInfo::GenerateChildProcessUniqueId()),
106 browser_context_(browser_context),
107 sudden_termination_allowed_(true),
108 ignore_input_events_(false) {
109 CHECK(!content::ExitedMainMessageLoop());
110 g_all_hosts.Get().AddWithID(this, id());
111 g_all_hosts.Get().set_check_on_null_data(true);
112 // Initialize |child_process_activity_time_| to a reasonable value.
113 mark_child_process_activity_time();
114 }
115
116 RenderProcessHost::~RenderProcessHost() {
117 // In unit tests, Release() might not have been called.
118 if (g_all_hosts.Get().Lookup(id()))
119 g_all_hosts.Get().Remove(id());
120 }
121
122 bool RenderProcessHost::HasConnection() const {
123 return channel_.get() != NULL;
124 }
125
126 void RenderProcessHost::Attach(IPC::Channel::Listener* listener,
127 int routing_id) {
128 listeners_.AddWithID(listener, routing_id);
129 }
130
131 void RenderProcessHost::Release(int listener_id) {
132 DCHECK(listeners_.Lookup(listener_id) != NULL);
133 listeners_.Remove(listener_id);
134
135 // Make sure that all associated resource requests are stopped.
136 CancelResourceRequests(listener_id);
137
138 #if defined(OS_WIN)
139 // Dump the handle table if handle auditing is enabled.
140 const CommandLine& browser_command_line =
141 *CommandLine::ForCurrentProcess();
142 if (browser_command_line.HasSwitch(switches::kAuditHandles) ||
143 browser_command_line.HasSwitch(switches::kAuditAllHandles)) {
144 DumpHandles();
145
146 // We wait to close the channels until the child process has finished
147 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone.
148 return;
149 }
150 #endif
151 Cleanup();
152 }
153
154 void RenderProcessHost::Cleanup() {
155 // When no other owners of this object, we can delete ourselves
156 if (listeners_.IsEmpty()) {
157 content::NotificationService::current()->Notify(
158 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
159 content::Source<RenderProcessHost>(this),
160 content::NotificationService::NoDetails());
161 MessageLoop::current()->DeleteSoon(FROM_HERE, this);
162 deleting_soon_ = true;
163 // It's important not to wait for the DeleteTask to delete the channel
164 // proxy. Kill it off now. That way, in case the profile is going away, the
165 // rest of the objects attached to this RenderProcessHost start going
166 // away first, since deleting the channel proxy will post a
167 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
168 channel_.reset();
169
170 // Remove ourself from the list of renderer processes so that we can't be
171 // reused in between now and when the Delete task runs.
172 g_all_hosts.Get().Remove(id());
173 }
174 }
175
176 void RenderProcessHost::ReportExpectingClose(int32 listener_id) {
177 listeners_expecting_close_.insert(listener_id);
178 }
179
180 void RenderProcessHost::AddPendingView() {
181 pending_views_++;
182 }
183
184 void RenderProcessHost::RemovePendingView() {
185 DCHECK(pending_views_);
186 pending_views_--;
187 }
188
189 void RenderProcessHost::UpdateMaxPageID(int32 page_id) {
190 if (page_id > max_page_id_)
191 max_page_id_ = page_id;
192 }
193
194 bool RenderProcessHost::FastShutdownForPageCount(size_t count) {
195 if (listeners_.size() == count)
196 return FastShutdownIfPossible();
197 return false;
198 }
199
200 // static
201 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
203 return iterator(g_all_hosts.Pointer());
204 }
205
206 // static
207 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
209 return g_all_hosts.Get().Lookup(render_process_id);
210 }
211
212 // static
213 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() {
214 size_t renderer_process_count = g_all_hosts.Get().size();
215
216 // NOTE: Sometimes it's necessary to create more render processes than
217 // GetMaxRendererProcessCount(), for instance when we want to create
218 // a renderer process for a browser context that has no existing
219 // renderers. This is OK in moderation, since the
220 // GetMaxRendererProcessCount() is conservative.
221
222 return run_renderer_in_process() ||
223 (renderer_process_count >= GetMaxRendererProcessCount());
224 }
225
226 // static
227 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
228 content::BrowserContext* browser_context,
229 const GURL& site_url) {
230 // First figure out which existing renderers we can use.
231 std::vector<RenderProcessHost*> suitable_renderers;
232 suitable_renderers.reserve(g_all_hosts.Get().size());
233
234 iterator iter(AllHostsIterator());
235 while (!iter.IsAtEnd()) {
236 if (run_renderer_in_process() ||
237 IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url))
238 suitable_renderers.push_back(iter.GetCurrentValue());
239
240 iter.Advance();
241 }
242
243 // Now pick a random suitable renderer, if we have any.
244 if (!suitable_renderers.empty()) {
245 int suitable_count = static_cast<int>(suitable_renderers.size());
246 int random_index = base::RandInt(0, suitable_count - 1);
247 return suitable_renderers[random_index];
248 }
249
250 return NULL;
251 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_process_host.h ('k') | content/browser/renderer_host/render_process_host_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698