| 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 |