OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 | 459 |
460 private: | 460 private: |
461 std::unique_ptr<std::map<int, SessionStorageNamespaceMap>> | 461 std::unique_ptr<std::map<int, SessionStorageNamespaceMap>> |
462 session_storage_namespaces_awaiting_close_; | 462 session_storage_namespaces_awaiting_close_; |
463 DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder); | 463 DISALLOW_COPY_AND_ASSIGN(SessionStorageHolder); |
464 }; | 464 }; |
465 | 465 |
466 const void* const kDefaultSubframeProcessHostHolderKey = | 466 const void* const kDefaultSubframeProcessHostHolderKey = |
467 &kDefaultSubframeProcessHostHolderKey; | 467 &kDefaultSubframeProcessHostHolderKey; |
468 | 468 |
| 469 // This class manages spare renderers. |
| 470 class SpareRenderProcessHostManager { |
| 471 public: |
| 472 SpareRenderProcessHostManager() {} |
| 473 |
| 474 void WarmupSpareRenderProcessHost(BrowserContext* browser_context) { |
| 475 StoragePartitionImpl* current_partition = |
| 476 static_cast<StoragePartitionImpl*>( |
| 477 BrowserContext::GetStoragePartition(browser_context, nullptr)); |
| 478 |
| 479 if (spare_render_process_host_ && |
| 480 matching_browser_context_ == browser_context && |
| 481 matching_storage_partition_ == current_partition) { |
| 482 return; // Nothing to warm up. |
| 483 } |
| 484 |
| 485 CleanupSpareRenderProcessHost(); |
| 486 |
| 487 matching_browser_context_ = browser_context; |
| 488 matching_storage_partition_ = current_partition; |
| 489 spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost( |
| 490 browser_context, current_partition, false /* is_for_guests_only */); |
| 491 |
| 492 spare_render_process_host_->Init(); |
| 493 } |
| 494 |
| 495 RenderProcessHost* MaybeTakeSpareRenderProcessHost( |
| 496 const BrowserContext* browser_context, |
| 497 const StoragePartition* partition, |
| 498 bool is_for_guests_only) { |
| 499 if (!spare_render_process_host_ || |
| 500 browser_context != matching_browser_context_ || |
| 501 partition != matching_storage_partition_ || is_for_guests_only) { |
| 502 // As a new RenderProcessHost will almost certainly be created, we cleanup |
| 503 // the non-matching one so as not to waste resources. |
| 504 CleanupSpareRenderProcessHost(); |
| 505 return nullptr; |
| 506 } |
| 507 |
| 508 if (!spare_render_process_host_->HasConnection()) { |
| 509 CleanupSpareRenderProcessHost(); |
| 510 return nullptr; |
| 511 } |
| 512 |
| 513 RenderProcessHost* rph = spare_render_process_host_; |
| 514 spare_render_process_host_ = nullptr; |
| 515 return rph; |
| 516 } |
| 517 |
| 518 void OnStoragePartitionShutdown(StoragePartition* partition) { |
| 519 if (partition == matching_storage_partition_) { |
| 520 CleanupSpareRenderProcessHost(); |
| 521 } |
| 522 } |
| 523 |
| 524 private: |
| 525 void CleanupSpareRenderProcessHost() { |
| 526 if (spare_render_process_host_) { |
| 527 spare_render_process_host_->Cleanup(); |
| 528 spare_render_process_host_ = nullptr; |
| 529 } |
| 530 } |
| 531 |
| 532 // This is a bare pointer, because RenderProcessHost manages the lifetime of |
| 533 // all its instances; see g_all_hosts, above. |
| 534 RenderProcessHost* spare_render_process_host_; |
| 535 |
| 536 // Used only to check if a creation request matches the |
| 537 // spare, and not accessed. |
| 538 const BrowserContext* matching_browser_context_ = nullptr; |
| 539 const StoragePartition* matching_storage_partition_ = nullptr; |
| 540 |
| 541 DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager); |
| 542 }; |
| 543 |
| 544 base::LazyInstance<SpareRenderProcessHostManager>::Leaky |
| 545 g_spare_render_process_host_manager = LAZY_INSTANCE_INITIALIZER; |
| 546 |
469 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 547 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, |
470 public RenderProcessHostObserver { | 548 public RenderProcessHostObserver { |
471 public: | 549 public: |
472 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) | 550 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) |
473 : browser_context_(browser_context) {} | 551 : browser_context_(browser_context) {} |
474 ~DefaultSubframeProcessHostHolder() override {} | 552 ~DefaultSubframeProcessHostHolder() override {} |
475 | 553 |
476 // Gets the correct render process to use for this SiteInstance. | 554 // Gets the correct render process to use for this SiteInstance. |
477 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, | 555 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, |
478 bool is_for_guests_only) { | 556 bool is_for_guests_only) { |
479 StoragePartition* default_partition = | 557 StoragePartition* default_partition = |
480 BrowserContext::GetDefaultStoragePartition(browser_context_); | 558 BrowserContext::GetDefaultStoragePartition(browser_context_); |
481 StoragePartition* partition = | 559 StoragePartition* partition = |
482 BrowserContext::GetStoragePartition(browser_context_, site_instance); | 560 BrowserContext::GetStoragePartition(browser_context_, site_instance); |
483 | 561 |
484 // Is this the default storage partition? If it isn't, then just give it its | 562 // Is this the default storage partition? If it isn't, then just give it its |
485 // own non-shared process. | 563 // own non-shared process. |
486 if (partition != default_partition || is_for_guests_only) { | 564 if (partition != default_partition || is_for_guests_only) { |
487 RenderProcessHostImpl* host = new RenderProcessHostImpl( | 565 RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost( |
488 browser_context_, static_cast<StoragePartitionImpl*>(partition), | 566 browser_context_, static_cast<StoragePartitionImpl*>(partition), |
489 is_for_guests_only); | 567 is_for_guests_only); |
490 host->SetIsNeverSuitableForReuse(); | 568 host->SetIsNeverSuitableForReuse(); |
491 return host; | 569 return host; |
492 } | 570 } |
493 | 571 |
494 // If we already have a shared host for the default storage partition, use | 572 // If we already have a shared host for the default storage partition, use |
495 // it. | 573 // it. |
496 if (host_) | 574 if (host_) |
497 return host_; | 575 return host_; |
498 | 576 |
499 host_ = new RenderProcessHostImpl( | 577 host_ = |
| 578 g_spare_render_process_host_manager.Get() |
| 579 .MaybeTakeSpareRenderProcessHost(browser_context_, partition, |
| 580 false /* is for guests only */); |
| 581 |
| 582 host_ = RenderProcessHostImpl::CreateRenderProcessHost( |
500 browser_context_, static_cast<StoragePartitionImpl*>(partition), | 583 browser_context_, static_cast<StoragePartitionImpl*>(partition), |
501 false /* for guests only */); | 584 false /* for guests only */); |
502 host_->SetIsNeverSuitableForReuse(); | 585 host_->SetIsNeverSuitableForReuse(); |
503 host_->AddObserver(this); | 586 host_->AddObserver(this); |
504 | 587 |
505 return host_; | 588 return host_; |
506 } | 589 } |
507 | 590 |
508 // Implementation of RenderProcessHostObserver. | 591 // Implementation of RenderProcessHostObserver. |
509 void RenderProcessHostDestroyed(RenderProcessHost* host) override { | 592 void RenderProcessHostDestroyed(RenderProcessHost* host) override { |
510 DCHECK_EQ(host_, host); | 593 DCHECK_EQ(host_, host); |
511 host_->RemoveObserver(this); | 594 host_->RemoveObserver(this); |
512 host_ = nullptr; | 595 host_ = nullptr; |
513 } | 596 } |
514 | 597 |
515 private: | 598 private: |
516 BrowserContext* browser_context_; | 599 BrowserContext* browser_context_; |
517 | 600 |
518 // The default subframe render process used for the default storage partition | 601 // The default subframe render process used for the default storage partition |
519 // of this BrowserContext. | 602 // of this BrowserContext. |
520 RenderProcessHostImpl* host_ = nullptr; | 603 RenderProcessHost* host_ = nullptr; |
521 }; | 604 }; |
522 | 605 |
523 void CreateMemoryCoordinatorHandle( | 606 void CreateMemoryCoordinatorHandle( |
524 int render_process_id, | 607 int render_process_id, |
525 const service_manager::BindSourceInfo& source_info, | 608 const service_manager::BindSourceInfo& source_info, |
526 mojom::MemoryCoordinatorHandleRequest request) { | 609 mojom::MemoryCoordinatorHandleRequest request) { |
527 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, | 610 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, |
528 std::move(request)); | 611 std::move(request)); |
529 } | 612 } |
530 | 613 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
901 max_count = std::min(max_count, kMaxRendererProcessCount); | 984 max_count = std::min(max_count, kMaxRendererProcessCount); |
902 } | 985 } |
903 return max_count; | 986 return max_count; |
904 } | 987 } |
905 | 988 |
906 // static | 989 // static |
907 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { | 990 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { |
908 g_max_renderer_count_override = count; | 991 g_max_renderer_count_override = count; |
909 } | 992 } |
910 | 993 |
| 994 // static |
| 995 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost( |
| 996 BrowserContext* browser_context, |
| 997 StoragePartitionImpl* storage_partition_impl, |
| 998 bool is_for_guests_only) { |
| 999 if (g_render_process_host_factory_) { |
| 1000 return g_render_process_host_factory_->CreateRenderProcessHost( |
| 1001 browser_context); |
| 1002 } |
| 1003 |
| 1004 return new RenderProcessHostImpl(browser_context, storage_partition_impl, |
| 1005 is_for_guests_only); |
| 1006 } |
| 1007 |
911 RenderProcessHostImpl::RenderProcessHostImpl( | 1008 RenderProcessHostImpl::RenderProcessHostImpl( |
912 BrowserContext* browser_context, | 1009 BrowserContext* browser_context, |
913 StoragePartitionImpl* storage_partition_impl, | 1010 StoragePartitionImpl* storage_partition_impl, |
914 bool is_for_guests_only) | 1011 bool is_for_guests_only) |
915 : fast_shutdown_started_(false), | 1012 : fast_shutdown_started_(false), |
916 deleting_soon_(false), | 1013 deleting_soon_(false), |
917 #ifndef NDEBUG | 1014 #ifndef NDEBUG |
918 is_self_deleted_(false), | 1015 is_self_deleted_(false), |
919 #endif | 1016 #endif |
920 pending_views_(0), | 1017 pending_views_(0), |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1972 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( | 2069 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>( |
1973 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); | 2070 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey)); |
1974 if (!tracker) { | 2071 if (!tracker) { |
1975 tracker = new SiteProcessCountTracker(); | 2072 tracker = new SiteProcessCountTracker(); |
1976 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, | 2073 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey, |
1977 base::WrapUnique(tracker)); | 2074 base::WrapUnique(tracker)); |
1978 } | 2075 } |
1979 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); | 2076 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID()); |
1980 } | 2077 } |
1981 | 2078 |
| 2079 // static |
| 2080 void RenderProcessHostImpl::OnStoragePartitionShutdown( |
| 2081 StoragePartition* partition) { |
| 2082 g_spare_render_process_host_manager.Get().OnStoragePartitionShutdown( |
| 2083 partition); |
| 2084 } |
| 2085 |
1982 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 2086 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
1983 return is_for_guests_only_; | 2087 return is_for_guests_only_; |
1984 } | 2088 } |
1985 | 2089 |
1986 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { | 2090 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { |
1987 return storage_partition_impl_; | 2091 return storage_partition_impl_; |
1988 } | 2092 } |
1989 | 2093 |
1990 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { | 2094 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { |
1991 command_line->AppendSwitchASCII( | 2095 command_line->AppendSwitchASCII( |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2912 host->GetID()) != | 3016 host->GetID()) != |
2913 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( | 3017 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( |
2914 browser_context, site_url)) { | 3018 browser_context, site_url)) { |
2915 return false; | 3019 return false; |
2916 } | 3020 } |
2917 | 3021 |
2918 return GetContentClient()->browser()->IsSuitableHost(host, site_url); | 3022 return GetContentClient()->browser()->IsSuitableHost(host, site_url); |
2919 } | 3023 } |
2920 | 3024 |
2921 // static | 3025 // static |
| 3026 void RenderProcessHost::WarmupSpareRenderProcessHost( |
| 3027 content::BrowserContext* browser_context) { |
| 3028 g_spare_render_process_host_manager.Get().WarmupSpareRenderProcessHost( |
| 3029 browser_context); |
| 3030 } |
| 3031 |
| 3032 // static |
2922 bool RenderProcessHost::run_renderer_in_process() { | 3033 bool RenderProcessHost::run_renderer_in_process() { |
2923 return g_run_renderer_in_process_; | 3034 return g_run_renderer_in_process_; |
2924 } | 3035 } |
2925 | 3036 |
2926 // static | 3037 // static |
2927 void RenderProcessHost::SetRunRendererInProcess(bool value) { | 3038 void RenderProcessHost::SetRunRendererInProcess(bool value) { |
2928 g_run_renderer_in_process_ = value; | 3039 g_run_renderer_in_process_ = value; |
2929 | 3040 |
2930 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 3041 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
2931 if (value) { | 3042 if (value) { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3107 default: | 3218 default: |
3108 break; | 3219 break; |
3109 } | 3220 } |
3110 | 3221 |
3111 // If not (or if none found), see if we should reuse an existing process. | 3222 // If not (or if none found), see if we should reuse an existing process. |
3112 if (!render_process_host && | 3223 if (!render_process_host && |
3113 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { | 3224 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { |
3114 render_process_host = GetExistingProcessHost(browser_context, site_url); | 3225 render_process_host = GetExistingProcessHost(browser_context, site_url); |
3115 } | 3226 } |
3116 | 3227 |
| 3228 // Try to use a spare process if one is found. |
| 3229 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( |
| 3230 BrowserContext::GetStoragePartition(browser_context, site_instance)); |
| 3231 if (!render_process_host) { |
| 3232 render_process_host = |
| 3233 g_spare_render_process_host_manager.Get() |
| 3234 .MaybeTakeSpareRenderProcessHost(browser_context, partition, |
| 3235 is_for_guests_only); |
| 3236 } |
| 3237 |
3117 // Otherwise (or if that fails), create a new one. | 3238 // Otherwise (or if that fails), create a new one. |
3118 if (!render_process_host) { | 3239 if (!render_process_host) { |
3119 if (g_render_process_host_factory_) { | 3240 render_process_host = |
3120 render_process_host = | 3241 CreateRenderProcessHost(browser_context, partition, is_for_guests_only); |
3121 g_render_process_host_factory_->CreateRenderProcessHost( | |
3122 browser_context); | |
3123 } else { | |
3124 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( | |
3125 BrowserContext::GetStoragePartition(browser_context, site_instance)); | |
3126 render_process_host = new RenderProcessHostImpl( | |
3127 browser_context, partition, is_for_guests_only); | |
3128 } | |
3129 } | 3242 } |
3130 return render_process_host; | 3243 return render_process_host; |
3131 } | 3244 } |
3132 | 3245 |
3133 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { | 3246 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { |
3134 // Create a persistent memory segment for renderer histograms only if | 3247 // Create a persistent memory segment for renderer histograms only if |
3135 // they're active in the browser. | 3248 // they're active in the browser. |
3136 if (!base::GlobalHistogramAllocator::Get()) | 3249 if (!base::GlobalHistogramAllocator::Get()) |
3137 return; | 3250 return; |
3138 | 3251 |
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3626 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; | 3739 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; |
3627 | 3740 |
3628 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. | 3741 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. |
3629 // Capture the error message in a crash key value. | 3742 // Capture the error message in a crash key value. |
3630 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); | 3743 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); |
3631 bad_message::ReceivedBadMessage(render_process_id, | 3744 bad_message::ReceivedBadMessage(render_process_id, |
3632 bad_message::RPH_MOJO_PROCESS_ERROR); | 3745 bad_message::RPH_MOJO_PROCESS_ERROR); |
3633 } | 3746 } |
3634 | 3747 |
3635 } // namespace content | 3748 } // namespace content |
OLD | NEW |