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