OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 // Represents the browser side of the browser <--> renderer communication | 5 // Represents the browser side of the browser <--> renderer communication |
6 // channel. There will be one RenderProcessHost per renderer process. | 6 // channel. There will be one RenderProcessHost per renderer process. |
7 | 7 |
8 #include "content/browser/renderer_host/render_process_host_impl.h" | 8 #include "content/browser/renderer_host/render_process_host_impl.h" |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 | 150 |
151 #include "third_party/skia/include/core/SkBitmap.h" | 151 #include "third_party/skia/include/core/SkBitmap.h" |
152 | 152 |
153 extern bool g_exited_main_message_loop; | 153 extern bool g_exited_main_message_loop; |
154 | 154 |
155 static const char* kSiteProcessMapKeyName = "content_site_process_map"; | 155 static const char* kSiteProcessMapKeyName = "content_site_process_map"; |
156 | 156 |
157 namespace content { | 157 namespace content { |
158 namespace { | 158 namespace { |
159 | 159 |
160 base::MessageLoop* g_in_process_thread; | |
161 | |
162 void CacheShaderInfo(int32 id, base::FilePath path) { | 160 void CacheShaderInfo(int32 id, base::FilePath path) { |
163 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); | 161 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); |
164 } | 162 } |
165 | 163 |
166 void RemoveShaderInfo(int32 id) { | 164 void RemoveShaderInfo(int32 id) { |
167 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id); | 165 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id); |
168 } | 166 } |
169 | 167 |
170 } // namespace | |
171 | |
172 #if !defined(CHROME_MULTIPLE_DLL) | |
173 | |
174 // This class creates the IO thread for the renderer when running in | |
175 // single-process mode. It's not used in multi-process mode. | |
176 class RendererMainThread : public base::Thread { | |
177 public: | |
178 explicit RendererMainThread(const std::string& channel_id) | |
179 : Thread("Chrome_InProcRendererThread"), | |
180 channel_id_(channel_id) { | |
181 } | |
182 | |
183 virtual ~RendererMainThread() { | |
184 Stop(); | |
185 } | |
186 | |
187 protected: | |
188 virtual void Init() OVERRIDE { | |
189 render_process_.reset(new RenderProcessImpl()); | |
190 new RenderThreadImpl(channel_id_); | |
191 g_in_process_thread = message_loop(); | |
192 } | |
193 | |
194 virtual void CleanUp() OVERRIDE { | |
195 g_in_process_thread = NULL; | |
196 render_process_.reset(); | |
197 | |
198 // It's a little lame to manually set this flag. But the single process | |
199 // RendererThread will receive the WM_QUIT. We don't need to assert on | |
200 // this thread, so just force the flag manually. | |
201 // If we want to avoid this, we could create the InProcRendererThread | |
202 // directly with _beginthreadex() rather than using the Thread class. | |
203 // We used to set this flag in the Init function above. However there | |
204 // other threads like WebThread which are created by this thread | |
205 // which resets this flag. Please see Thread::StartWithOptions. Setting | |
206 // this flag to true in Cleanup works around these problems. | |
207 SetThreadWasQuitProperly(true); | |
208 } | |
209 | |
210 private: | |
211 std::string channel_id_; | |
212 scoped_ptr<RenderProcess> render_process_; | |
213 | |
214 DISALLOW_COPY_AND_ASSIGN(RendererMainThread); | |
215 }; | |
216 | |
217 #endif | |
218 | |
219 namespace { | |
220 | |
221 // Helper class that we pass to ResourceMessageFilter so that it can find the | 168 // Helper class that we pass to ResourceMessageFilter so that it can find the |
222 // right net::URLRequestContext for a request. | 169 // right net::URLRequestContext for a request. |
223 class RendererURLRequestContextSelector | 170 class RendererURLRequestContextSelector |
224 : public ResourceMessageFilter::URLRequestContextSelector { | 171 : public ResourceMessageFilter::URLRequestContextSelector { |
225 public: | 172 public: |
226 RendererURLRequestContextSelector(BrowserContext* browser_context, | 173 RendererURLRequestContextSelector(BrowserContext* browser_context, |
227 int render_child_id) | 174 int render_child_id) |
228 : request_context_(browser_context->GetRequestContextForRenderProcess( | 175 : request_context_(browser_context->GetRequestContextForRenderProcess( |
229 render_child_id)), | 176 render_child_id)), |
230 media_request_context_( | 177 media_request_context_( |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy, | 279 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy, |
333 bool* success) { | 280 bool* success) { |
334 AddBaseHandleClosePolicy(policy); | 281 AddBaseHandleClosePolicy(policy); |
335 GetContentClient()->browser()->PreSpawnRenderer(policy, success); | 282 GetContentClient()->browser()->PreSpawnRenderer(policy, success); |
336 } | 283 } |
337 }; | 284 }; |
338 #endif // OS_WIN | 285 #endif // OS_WIN |
339 | 286 |
340 } // namespace | 287 } // namespace |
341 | 288 |
| 289 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; |
| 290 |
| 291 void RenderProcessHost::RegisterRendererMainThreadFactory( |
| 292 RendererMainThreadFactoryFunction create) { |
| 293 g_renderer_main_thread_factory = create; |
| 294 } |
| 295 |
| 296 base::MessageLoop* g_in_process_thread; |
| 297 |
| 298 base::MessageLoop* |
| 299 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() { |
| 300 return g_in_process_thread; |
| 301 } |
| 302 |
342 // Stores the maximum number of renderer processes the content module can | 303 // Stores the maximum number of renderer processes the content module can |
343 // create. | 304 // create. |
344 static size_t g_max_renderer_count_override = 0; | 305 static size_t g_max_renderer_count_override = 0; |
345 | 306 |
346 // static | 307 // static |
347 size_t RenderProcessHost::GetMaxRendererProcessCount() { | 308 size_t RenderProcessHost::GetMaxRendererProcessCount() { |
348 if (g_max_renderer_count_override) | 309 if (g_max_renderer_count_override) |
349 return g_max_renderer_count_override; | 310 return g_max_renderer_count_override; |
350 | 311 |
351 // Defines the maximum number of renderer processes according to the | 312 // Defines the maximum number of renderer processes according to the |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 this, | 465 this, |
505 BrowserThread::GetMessageLoopProxyForThread( | 466 BrowserThread::GetMessageLoopProxyForThread( |
506 BrowserThread::IO).get())); | 467 BrowserThread::IO).get())); |
507 | 468 |
508 // Call the embedder first so that their IPC filters have priority. | 469 // Call the embedder first so that their IPC filters have priority. |
509 GetContentClient()->browser()->RenderProcessHostCreated(this); | 470 GetContentClient()->browser()->RenderProcessHostCreated(this); |
510 | 471 |
511 CreateMessageFilters(); | 472 CreateMessageFilters(); |
512 | 473 |
513 // Single-process mode not supported in multiple-dll mode currently. | 474 // Single-process mode not supported in multiple-dll mode currently. |
514 #if !defined(CHROME_MULTIPLE_DLL) | 475 if (run_renderer_in_process() && g_renderer_main_thread_factory) { |
515 if (run_renderer_in_process()) { | |
516 // Crank up a thread and run the initialization there. With the way that | 476 // Crank up a thread and run the initialization there. With the way that |
517 // messages flow between the browser and renderer, this thread is required | 477 // messages flow between the browser and renderer, this thread is required |
518 // to prevent a deadlock in single-process mode. Since the primordial | 478 // to prevent a deadlock in single-process mode. Since the primordial |
519 // thread in the renderer process runs the WebKit code and can sometimes | 479 // thread in the renderer process runs the WebKit code and can sometimes |
520 // make blocking calls to the UI thread (i.e. this thread), they need to run | 480 // make blocking calls to the UI thread (i.e. this thread), they need to run |
521 // on separate threads. | 481 // on separate threads. |
522 in_process_renderer_.reset(new RendererMainThread(channel_id)); | 482 in_process_renderer_.reset(g_renderer_main_thread_factory(channel_id)); |
523 | 483 |
524 base::Thread::Options options; | 484 base::Thread::Options options; |
525 #if defined(OS_WIN) && !defined(OS_MACOSX) | 485 #if defined(OS_WIN) && !defined(OS_MACOSX) |
526 // In-process plugins require this to be a UI message loop. | 486 // In-process plugins require this to be a UI message loop. |
527 options.message_loop_type = base::MessageLoop::TYPE_UI; | 487 options.message_loop_type = base::MessageLoop::TYPE_UI; |
528 #else | 488 #else |
529 // We can't have multiple UI loops on Linux and Android, so we don't support | 489 // We can't have multiple UI loops on Linux and Android, so we don't support |
530 // in-process plugins. | 490 // in-process plugins. |
531 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; | 491 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; |
532 #endif | 492 #endif |
533 in_process_renderer_->StartWithOptions(options); | 493 in_process_renderer_->StartWithOptions(options); |
534 | 494 |
| 495 g_in_process_thread = in_process_renderer_->message_loop(); |
| 496 |
535 OnProcessLaunched(); // Fake a callback that the process is ready. | 497 OnProcessLaunched(); // Fake a callback that the process is ready. |
536 } else | 498 } else { |
537 #endif // !CHROME_MULTIPLE_DLL | |
538 { | |
539 // Build command line for renderer. We call AppendRendererCommandLine() | 499 // Build command line for renderer. We call AppendRendererCommandLine() |
540 // first so the process type argument will appear first. | 500 // first so the process type argument will appear first. |
541 CommandLine* cmd_line = new CommandLine(renderer_path); | 501 CommandLine* cmd_line = new CommandLine(renderer_path); |
542 if (!renderer_prefix.empty()) | 502 if (!renderer_prefix.empty()) |
543 cmd_line->PrependWrapper(renderer_prefix); | 503 cmd_line->PrependWrapper(renderer_prefix); |
544 AppendRendererCommandLine(cmd_line); | 504 AppendRendererCommandLine(cmd_line); |
545 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); | 505 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); |
546 | 506 |
547 // Spawn the child process asynchronously to avoid blocking the UI thread. | 507 // Spawn the child process asynchronously to avoid blocking the UI thread. |
548 // As long as there's no renderer prefix, we can use the zygote process | 508 // As long as there's no renderer prefix, we can use the zygote process |
(...skipping 1058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1607 | 1567 |
1608 // Only register valid, non-empty sites. Empty or invalid sites will not | 1568 // Only register valid, non-empty sites. Empty or invalid sites will not |
1609 // use process-per-site mode. We cannot check whether the process has | 1569 // use process-per-site mode. We cannot check whether the process has |
1610 // appropriate bindings here, because the bindings have not yet been granted. | 1570 // appropriate bindings here, because the bindings have not yet been granted. |
1611 std::string site = SiteInstance::GetSiteForURL(browser_context, url) | 1571 std::string site = SiteInstance::GetSiteForURL(browser_context, url) |
1612 .possibly_invalid_spec(); | 1572 .possibly_invalid_spec(); |
1613 if (!site.empty()) | 1573 if (!site.empty()) |
1614 map->RegisterProcess(site, process); | 1574 map->RegisterProcess(site, process); |
1615 } | 1575 } |
1616 | 1576 |
1617 base::MessageLoop* | |
1618 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() { | |
1619 return g_in_process_thread; | |
1620 } | |
1621 | |
1622 void RenderProcessHostImpl::ProcessDied(bool already_dead) { | 1577 void RenderProcessHostImpl::ProcessDied(bool already_dead) { |
1623 // Our child process has died. If we didn't expect it, it's a crash. | 1578 // Our child process has died. If we didn't expect it, it's a crash. |
1624 // In any case, we need to let everyone know it's gone. | 1579 // In any case, we need to let everyone know it's gone. |
1625 // The OnChannelError notification can fire multiple times due to nested sync | 1580 // The OnChannelError notification can fire multiple times due to nested sync |
1626 // calls to a renderer. If we don't have a valid channel here it means we | 1581 // calls to a renderer. If we don't have a valid channel here it means we |
1627 // already handled the error. | 1582 // already handled the error. |
1628 | 1583 |
1629 // child_process_launcher_ can be NULL in single process mode or if fast | 1584 // child_process_launcher_ can be NULL in single process mode or if fast |
1630 // termination happened. | 1585 // termination happened. |
1631 int exit_code = 0; | 1586 int exit_code = 0; |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1807 // Skip widgets in other processes. | 1762 // Skip widgets in other processes. |
1808 if (widgets[i]->GetProcess()->GetID() != GetID()) | 1763 if (widgets[i]->GetProcess()->GetID() != GetID()) |
1809 continue; | 1764 continue; |
1810 | 1765 |
1811 RenderViewHost* rvh = RenderViewHost::From(widgets[i]); | 1766 RenderViewHost* rvh = RenderViewHost::From(widgets[i]); |
1812 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences()); | 1767 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences()); |
1813 } | 1768 } |
1814 } | 1769 } |
1815 | 1770 |
1816 } // namespace content | 1771 } // namespace content |
OLD | NEW |