OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/render_process_host.h" | 5 #include "content/browser/renderer_host/render_process_host.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/lazy_instance.h" |
8 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
9 #include "base/sys_info.h" | 10 #include "base/sys_info.h" |
10 #include "content/browser/browser_main.h" | 11 #include "content/browser/browser_main.h" |
11 #include "content/browser/child_process_security_policy.h" | 12 #include "content/browser/child_process_security_policy.h" |
12 #include "content/browser/webui/web_ui_factory.h" | 13 #include "content/browser/webui/web_ui_factory.h" |
13 #include "content/common/child_process_info.h" | 14 #include "content/common/child_process_info.h" |
14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
15 #include "content/public/browser/content_browser_client.h" | 16 #include "content/public/browser/content_browser_client.h" |
16 #include "content/public/browser/notification_service.h" | 17 #include "content/public/browser/notification_service.h" |
17 #include "content/public/browser/notification_types.h" | 18 #include "content/public/browser/notification_types.h" |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 return false; | 76 return false; |
76 | 77 |
77 if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()) != | 78 if (ChildProcessSecurityPolicy::GetInstance()->HasWebUIBindings(host->id()) != |
78 content::WebUIFactory::Get()->HasWebUIScheme(site_url)) | 79 content::WebUIFactory::Get()->HasWebUIScheme(site_url)) |
79 return false; | 80 return false; |
80 | 81 |
81 return content::GetContentClient()->browser()->IsSuitableHost(host, site_url); | 82 return content::GetContentClient()->browser()->IsSuitableHost(host, site_url); |
82 } | 83 } |
83 | 84 |
84 // the global list of all renderer processes | 85 // the global list of all renderer processes |
85 IDMap<RenderProcessHost> all_hosts; | 86 base::LazyInstance<IDMap<RenderProcessHost>, |
| 87 base::LeakyLazyInstanceTraits<IDMap<RenderProcessHost> > > |
| 88 g_all_hosts(base::LINKER_INITIALIZED); |
86 | 89 |
87 } // namespace | 90 } // namespace |
88 | 91 |
89 // static | 92 // static |
90 bool RenderProcessHost::run_renderer_in_process_ = false; | 93 bool RenderProcessHost::run_renderer_in_process_ = false; |
91 | 94 |
92 // static | 95 // static |
93 void RenderProcessHost::SetMaxRendererProcessCountForTest(size_t count) { | 96 void RenderProcessHost::SetMaxRendererProcessCountForTest(size_t count) { |
94 max_renderer_count_override = count; | 97 max_renderer_count_override = count; |
95 } | 98 } |
96 | 99 |
97 RenderProcessHost::RenderProcessHost(content::BrowserContext* browser_context) | 100 RenderProcessHost::RenderProcessHost(content::BrowserContext* browser_context) |
98 : max_page_id_(-1), | 101 : max_page_id_(-1), |
99 fast_shutdown_started_(false), | 102 fast_shutdown_started_(false), |
100 deleting_soon_(false), | 103 deleting_soon_(false), |
101 pending_views_(0), | 104 pending_views_(0), |
102 id_(ChildProcessInfo::GenerateChildProcessUniqueId()), | 105 id_(ChildProcessInfo::GenerateChildProcessUniqueId()), |
103 browser_context_(browser_context), | 106 browser_context_(browser_context), |
104 sudden_termination_allowed_(true), | 107 sudden_termination_allowed_(true), |
105 ignore_input_events_(false) { | 108 ignore_input_events_(false) { |
106 CHECK(!content::ExitedMainMessageLoop()); | 109 CHECK(!content::ExitedMainMessageLoop()); |
107 all_hosts.AddWithID(this, id()); | 110 g_all_hosts.Get().AddWithID(this, id()); |
108 all_hosts.set_check_on_null_data(true); | 111 g_all_hosts.Get().set_check_on_null_data(true); |
109 // Initialize |child_process_activity_time_| to a reasonable value. | 112 // Initialize |child_process_activity_time_| to a reasonable value. |
110 mark_child_process_activity_time(); | 113 mark_child_process_activity_time(); |
111 } | 114 } |
112 | 115 |
113 RenderProcessHost::~RenderProcessHost() { | 116 RenderProcessHost::~RenderProcessHost() { |
114 // In unit tests, Release() might not have been called. | 117 // In unit tests, Release() might not have been called. |
115 if (all_hosts.Lookup(id())) | 118 if (g_all_hosts.Get().Lookup(id())) |
116 all_hosts.Remove(id()); | 119 g_all_hosts.Get().Remove(id()); |
117 } | 120 } |
118 | 121 |
119 bool RenderProcessHost::HasConnection() const { | 122 bool RenderProcessHost::HasConnection() const { |
120 return channel_.get() != NULL; | 123 return channel_.get() != NULL; |
121 } | 124 } |
122 | 125 |
123 void RenderProcessHost::Attach(IPC::Channel::Listener* listener, | 126 void RenderProcessHost::Attach(IPC::Channel::Listener* listener, |
124 int routing_id) { | 127 int routing_id) { |
125 listeners_.AddWithID(listener, routing_id); | 128 listeners_.AddWithID(listener, routing_id); |
126 } | 129 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 deleting_soon_ = true; | 162 deleting_soon_ = true; |
160 // It's important not to wait for the DeleteTask to delete the channel | 163 // It's important not to wait for the DeleteTask to delete the channel |
161 // proxy. Kill it off now. That way, in case the profile is going away, the | 164 // proxy. Kill it off now. That way, in case the profile is going away, the |
162 // rest of the objects attached to this RenderProcessHost start going | 165 // rest of the objects attached to this RenderProcessHost start going |
163 // away first, since deleting the channel proxy will post a | 166 // away first, since deleting the channel proxy will post a |
164 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. | 167 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. |
165 channel_.reset(); | 168 channel_.reset(); |
166 | 169 |
167 // Remove ourself from the list of renderer processes so that we can't be | 170 // Remove ourself from the list of renderer processes so that we can't be |
168 // reused in between now and when the Delete task runs. | 171 // reused in between now and when the Delete task runs. |
169 all_hosts.Remove(id()); | 172 g_all_hosts.Get().Remove(id()); |
170 } | 173 } |
171 } | 174 } |
172 | 175 |
173 void RenderProcessHost::ReportExpectingClose(int32 listener_id) { | 176 void RenderProcessHost::ReportExpectingClose(int32 listener_id) { |
174 listeners_expecting_close_.insert(listener_id); | 177 listeners_expecting_close_.insert(listener_id); |
175 } | 178 } |
176 | 179 |
177 void RenderProcessHost::AddPendingView() { | 180 void RenderProcessHost::AddPendingView() { |
178 pending_views_++; | 181 pending_views_++; |
179 } | 182 } |
(...skipping 10 matching lines...) Expand all Loading... |
190 | 193 |
191 bool RenderProcessHost::FastShutdownForPageCount(size_t count) { | 194 bool RenderProcessHost::FastShutdownForPageCount(size_t count) { |
192 if (listeners_.size() == count) | 195 if (listeners_.size() == count) |
193 return FastShutdownIfPossible(); | 196 return FastShutdownIfPossible(); |
194 return false; | 197 return false; |
195 } | 198 } |
196 | 199 |
197 // static | 200 // static |
198 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() { | 201 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() { |
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 202 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
200 return iterator(&all_hosts); | 203 return iterator(g_all_hosts.Pointer()); |
201 } | 204 } |
202 | 205 |
203 // static | 206 // static |
204 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { | 207 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { |
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 208 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
206 return all_hosts.Lookup(render_process_id); | 209 return g_all_hosts.Get().Lookup(render_process_id); |
207 } | 210 } |
208 | 211 |
209 // static | 212 // static |
210 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { | 213 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { |
211 size_t renderer_process_count = all_hosts.size(); | 214 size_t renderer_process_count = g_all_hosts.Get().size(); |
212 | 215 |
213 // NOTE: Sometimes it's necessary to create more render processes than | 216 // NOTE: Sometimes it's necessary to create more render processes than |
214 // GetMaxRendererProcessCount(), for instance when we want to create | 217 // GetMaxRendererProcessCount(), for instance when we want to create |
215 // a renderer process for a browser context that has no existing | 218 // a renderer process for a browser context that has no existing |
216 // renderers. This is OK in moderation, since the | 219 // renderers. This is OK in moderation, since the |
217 // GetMaxRendererProcessCount() is conservative. | 220 // GetMaxRendererProcessCount() is conservative. |
218 | 221 |
219 return run_renderer_in_process() || | 222 return run_renderer_in_process() || |
220 (renderer_process_count >= GetMaxRendererProcessCount()); | 223 (renderer_process_count >= GetMaxRendererProcessCount()); |
221 } | 224 } |
222 | 225 |
223 // static | 226 // static |
224 RenderProcessHost* RenderProcessHost::GetExistingProcessHost( | 227 RenderProcessHost* RenderProcessHost::GetExistingProcessHost( |
225 content::BrowserContext* browser_context, | 228 content::BrowserContext* browser_context, |
226 const GURL& site_url) { | 229 const GURL& site_url) { |
227 // First figure out which existing renderers we can use. | 230 // First figure out which existing renderers we can use. |
228 std::vector<RenderProcessHost*> suitable_renderers; | 231 std::vector<RenderProcessHost*> suitable_renderers; |
229 suitable_renderers.reserve(all_hosts.size()); | 232 suitable_renderers.reserve(g_all_hosts.Get().size()); |
230 | 233 |
231 iterator iter(AllHostsIterator()); | 234 iterator iter(AllHostsIterator()); |
232 while (!iter.IsAtEnd()) { | 235 while (!iter.IsAtEnd()) { |
233 if (run_renderer_in_process() || | 236 if (run_renderer_in_process() || |
234 IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url)) | 237 IsSuitableHost(iter.GetCurrentValue(), browser_context, site_url)) |
235 suitable_renderers.push_back(iter.GetCurrentValue()); | 238 suitable_renderers.push_back(iter.GetCurrentValue()); |
236 | 239 |
237 iter.Advance(); | 240 iter.Advance(); |
238 } | 241 } |
239 | 242 |
240 // Now pick a random suitable renderer, if we have any. | 243 // Now pick a random suitable renderer, if we have any. |
241 if (!suitable_renderers.empty()) { | 244 if (!suitable_renderers.empty()) { |
242 int suitable_count = static_cast<int>(suitable_renderers.size()); | 245 int suitable_count = static_cast<int>(suitable_renderers.size()); |
243 int random_index = base::RandInt(0, suitable_count - 1); | 246 int random_index = base::RandInt(0, suitable_count - 1); |
244 return suitable_renderers[random_index]; | 247 return suitable_renderers[random_index]; |
245 } | 248 } |
246 | 249 |
247 return NULL; | 250 return NULL; |
248 } | 251 } |
OLD | NEW |