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 StartSpareRenderProcessHost(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 matching_browser_context_ = browser_context; | |
485 matching_storage_partition_ = current_partition; | |
486 spare_render_process_host_ = RenderProcessHostImpl::CreateRenderProcessHost( | |
Benoit L
2017/06/09 14:35:22
Wouldn't this leak the previous one in the case wh
mattcary
2017/06/09 14:40:53
I don't think so. RPH seem to handle their own del
| |
487 browser_context, current_partition, false /* is_for_guests_only */); | |
488 spare_render_process_host_->Init(); | |
489 } | |
490 | |
491 RenderProcessHost* MaybeTakeSpareRenderProcessHost( | |
492 const BrowserContext* browser_context, | |
493 const StoragePartition* partition, | |
494 bool is_for_guests_only) { | |
495 if (!spare_render_process_host_ || | |
496 browser_context != matching_browser_context_ || | |
497 partition != matching_storage_partition_ || is_for_guests_only) { | |
498 // As a new RenderProcessHost will almost certainly be created, we delete | |
499 // the non-matching one so as not to waste resources. | |
500 // TODO(mattcary): is deleting the RPH enough? | |
501 CleanupSpareRenderProcessHost(); | |
502 return nullptr; | |
503 } | |
504 RenderProcessHost* rph = spare_render_process_host_; | |
505 spare_render_process_host_ = nullptr; | |
506 return rph; | |
507 } | |
508 | |
509 void CleanupSpareRenderProcessHost() { | |
510 if (spare_render_process_host_) { | |
511 spare_render_process_host_->Cleanup(); | |
512 spare_render_process_host_ = nullptr; | |
513 } | |
514 } | |
515 | |
516 private: | |
517 RenderProcessHost* spare_render_process_host_; | |
518 | |
519 // Used only to check if a creation request matches the | |
520 // spare, and not accessed. | |
521 const BrowserContext* matching_browser_context_ = nullptr; | |
522 const StoragePartition* matching_storage_partition_ = nullptr; | |
523 | |
524 DISALLOW_COPY_AND_ASSIGN(SpareRenderProcessHostManager); | |
525 }; | |
526 | |
527 SpareRenderProcessHostManager* g_spare_render_process_host_manager = nullptr; | |
528 | |
468 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, | 529 class DefaultSubframeProcessHostHolder : public base::SupportsUserData::Data, |
469 public RenderProcessHostObserver { | 530 public RenderProcessHostObserver { |
470 public: | 531 public: |
471 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) | 532 explicit DefaultSubframeProcessHostHolder(BrowserContext* browser_context) |
472 : browser_context_(browser_context) {} | 533 : browser_context_(browser_context) {} |
473 ~DefaultSubframeProcessHostHolder() override {} | 534 ~DefaultSubframeProcessHostHolder() override {} |
474 | 535 |
475 // Gets the correct render process to use for this SiteInstance. | 536 // Gets the correct render process to use for this SiteInstance. |
476 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, | 537 RenderProcessHost* GetProcessHost(SiteInstance* site_instance, |
477 bool is_for_guests_only) { | 538 bool is_for_guests_only) { |
478 StoragePartition* default_partition = | 539 StoragePartition* default_partition = |
479 BrowserContext::GetDefaultStoragePartition(browser_context_); | 540 BrowserContext::GetDefaultStoragePartition(browser_context_); |
480 StoragePartition* partition = | 541 StoragePartition* partition = |
481 BrowserContext::GetStoragePartition(browser_context_, site_instance); | 542 BrowserContext::GetStoragePartition(browser_context_, site_instance); |
482 | 543 |
483 // Is this the default storage partition? If it isn't, then just give it its | 544 // Is this the default storage partition? If it isn't, then just give it its |
484 // own non-shared process. | 545 // own non-shared process. |
485 if (partition != default_partition || is_for_guests_only) { | 546 if (partition != default_partition || is_for_guests_only) { |
486 RenderProcessHostImpl* host = new RenderProcessHostImpl( | 547 RenderProcessHost* host = RenderProcessHostImpl::CreateRenderProcessHost( |
487 browser_context_, static_cast<StoragePartitionImpl*>(partition), | 548 browser_context_, static_cast<StoragePartitionImpl*>(partition), |
488 is_for_guests_only); | 549 is_for_guests_only); |
489 host->SetIsNeverSuitableForReuse(); | 550 host->SetIsNeverSuitableForReuse(); |
490 return host; | 551 return host; |
491 } | 552 } |
492 | 553 |
493 // If we already have a shared host for the default storage partition, use | 554 // If we already have a shared host for the default storage partition, use |
494 // it. | 555 // it. |
495 if (host_) | 556 if (host_) |
496 return host_; | 557 return host_; |
497 | 558 |
498 host_ = new RenderProcessHostImpl( | 559 if (g_spare_render_process_host_manager) { |
560 host_ = | |
561 g_spare_render_process_host_manager->MaybeTakeSpareRenderProcessHost( | |
562 browser_context_, partition, false /* is for guests only */); | |
563 } | |
564 | |
565 host_ = RenderProcessHostImpl::CreateRenderProcessHost( | |
499 browser_context_, static_cast<StoragePartitionImpl*>(partition), | 566 browser_context_, static_cast<StoragePartitionImpl*>(partition), |
500 false /* for guests only */); | 567 false /* for guests only */); |
501 host_->SetIsNeverSuitableForReuse(); | 568 host_->SetIsNeverSuitableForReuse(); |
502 host_->AddObserver(this); | 569 host_->AddObserver(this); |
503 | 570 |
504 return host_; | 571 return host_; |
505 } | 572 } |
506 | 573 |
507 // Implementation of RenderProcessHostObserver. | 574 // Implementation of RenderProcessHostObserver. |
508 void RenderProcessHostDestroyed(RenderProcessHost* host) override { | 575 void RenderProcessHostDestroyed(RenderProcessHost* host) override { |
509 DCHECK_EQ(host_, host); | 576 DCHECK_EQ(host_, host); |
510 host_->RemoveObserver(this); | 577 host_->RemoveObserver(this); |
511 host_ = nullptr; | 578 host_ = nullptr; |
512 } | 579 } |
513 | 580 |
514 private: | 581 private: |
515 BrowserContext* browser_context_; | 582 BrowserContext* browser_context_; |
516 | 583 |
517 // The default subframe render process used for the default storage partition | 584 // The default subframe render process used for the default storage partition |
518 // of this BrowserContext. | 585 // of this BrowserContext. |
519 RenderProcessHostImpl* host_ = nullptr; | 586 RenderProcessHost* host_ = nullptr; |
520 }; | 587 }; |
521 | 588 |
522 void CreateMemoryCoordinatorHandle( | 589 void CreateMemoryCoordinatorHandle( |
523 int render_process_id, | 590 int render_process_id, |
524 const service_manager::BindSourceInfo& source_info, | 591 const service_manager::BindSourceInfo& source_info, |
525 mojom::MemoryCoordinatorHandleRequest request) { | 592 mojom::MemoryCoordinatorHandleRequest request) { |
526 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, | 593 MemoryCoordinatorImpl::GetInstance()->CreateHandle(render_process_id, |
527 std::move(request)); | 594 std::move(request)); |
528 } | 595 } |
529 | 596 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
900 max_count = std::min(max_count, kMaxRendererProcessCount); | 967 max_count = std::min(max_count, kMaxRendererProcessCount); |
901 } | 968 } |
902 return max_count; | 969 return max_count; |
903 } | 970 } |
904 | 971 |
905 // static | 972 // static |
906 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { | 973 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { |
907 g_max_renderer_count_override = count; | 974 g_max_renderer_count_override = count; |
908 } | 975 } |
909 | 976 |
977 // static | |
978 RenderProcessHost* RenderProcessHostImpl::CreateRenderProcessHost( | |
979 BrowserContext* browser_context, | |
980 StoragePartitionImpl* storage_partition_impl, | |
981 bool is_for_guests_only) { | |
982 if (g_render_process_host_factory_) { | |
983 return g_render_process_host_factory_->CreateRenderProcessHost( | |
984 browser_context); | |
985 } | |
986 | |
987 return new RenderProcessHostImpl(browser_context, storage_partition_impl, | |
988 is_for_guests_only); | |
989 } | |
990 | |
910 RenderProcessHostImpl::RenderProcessHostImpl( | 991 RenderProcessHostImpl::RenderProcessHostImpl( |
911 BrowserContext* browser_context, | 992 BrowserContext* browser_context, |
912 StoragePartitionImpl* storage_partition_impl, | 993 StoragePartitionImpl* storage_partition_impl, |
913 bool is_for_guests_only) | 994 bool is_for_guests_only) |
914 : fast_shutdown_started_(false), | 995 : fast_shutdown_started_(false), |
915 deleting_soon_(false), | 996 deleting_soon_(false), |
916 #ifndef NDEBUG | 997 #ifndef NDEBUG |
917 is_self_deleted_(false), | 998 is_self_deleted_(false), |
918 #endif | 999 #endif |
919 pending_views_(0), | 1000 pending_views_(0), |
(...skipping 1988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2908 host->GetID()) != | 2989 host->GetID()) != |
2909 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( | 2990 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( |
2910 browser_context, site_url)) { | 2991 browser_context, site_url)) { |
2911 return false; | 2992 return false; |
2912 } | 2993 } |
2913 | 2994 |
2914 return GetContentClient()->browser()->IsSuitableHost(host, site_url); | 2995 return GetContentClient()->browser()->IsSuitableHost(host, site_url); |
2915 } | 2996 } |
2916 | 2997 |
2917 // static | 2998 // static |
2999 void RenderProcessHost::StartSpareRenderProcessHost( | |
3000 content::BrowserContext* browser_context) { | |
3001 if (!g_spare_render_process_host_manager) { | |
Benoit L
2017/06/09 14:35:22
since this is a leaky singleton, what about a Lazy
mattcary
2017/06/09 14:40:53
Done
| |
3002 g_spare_render_process_host_manager = new SpareRenderProcessHostManager(); | |
3003 } | |
3004 g_spare_render_process_host_manager->StartSpareRenderProcessHost( | |
3005 browser_context); | |
3006 } | |
3007 | |
3008 // static | |
2918 bool RenderProcessHost::run_renderer_in_process() { | 3009 bool RenderProcessHost::run_renderer_in_process() { |
2919 return g_run_renderer_in_process_; | 3010 return g_run_renderer_in_process_; |
2920 } | 3011 } |
2921 | 3012 |
2922 // static | 3013 // static |
2923 void RenderProcessHost::SetRunRendererInProcess(bool value) { | 3014 void RenderProcessHost::SetRunRendererInProcess(bool value) { |
2924 g_run_renderer_in_process_ = value; | 3015 g_run_renderer_in_process_ = value; |
2925 | 3016 |
2926 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 3017 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
2927 if (value) { | 3018 if (value) { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3103 default: | 3194 default: |
3104 break; | 3195 break; |
3105 } | 3196 } |
3106 | 3197 |
3107 // If not (or if none found), see if we should reuse an existing process. | 3198 // If not (or if none found), see if we should reuse an existing process. |
3108 if (!render_process_host && | 3199 if (!render_process_host && |
3109 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { | 3200 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { |
3110 render_process_host = GetExistingProcessHost(browser_context, site_url); | 3201 render_process_host = GetExistingProcessHost(browser_context, site_url); |
3111 } | 3202 } |
3112 | 3203 |
3204 // Try to use a spare process if one is found. | |
3205 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( | |
3206 BrowserContext::GetStoragePartition(browser_context, site_instance)); | |
3207 if (!render_process_host && g_spare_render_process_host_manager) { | |
3208 render_process_host = | |
3209 g_spare_render_process_host_manager->MaybeTakeSpareRenderProcessHost( | |
3210 browser_context, partition, is_for_guests_only); | |
3211 } | |
3212 | |
3113 // Otherwise (or if that fails), create a new one. | 3213 // Otherwise (or if that fails), create a new one. |
3114 if (!render_process_host) { | 3214 if (!render_process_host) { |
3115 if (g_render_process_host_factory_) { | 3215 render_process_host = |
3116 render_process_host = | 3216 CreateRenderProcessHost(browser_context, partition, is_for_guests_only); |
Benoit L
2017/06/09 14:35:22
Doesn't this bypass the factory?
mattcary
2017/06/09 14:40:53
Nope, that's exactly why I added CreateRenderProce
| |
3117 g_render_process_host_factory_->CreateRenderProcessHost( | |
3118 browser_context, site_instance); | |
3119 } else { | |
3120 StoragePartitionImpl* partition = static_cast<StoragePartitionImpl*>( | |
3121 BrowserContext::GetStoragePartition(browser_context, site_instance)); | |
3122 render_process_host = new RenderProcessHostImpl( | |
3123 browser_context, partition, is_for_guests_only); | |
3124 } | |
3125 } | 3217 } |
3126 return render_process_host; | 3218 return render_process_host; |
3127 } | 3219 } |
3128 | 3220 |
3129 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { | 3221 void RenderProcessHostImpl::CreateSharedRendererHistogramAllocator() { |
3130 // Create a persistent memory segment for renderer histograms only if | 3222 // Create a persistent memory segment for renderer histograms only if |
3131 // they're active in the browser. | 3223 // they're active in the browser. |
3132 if (!base::GlobalHistogramAllocator::Get()) | 3224 if (!base::GlobalHistogramAllocator::Get()) |
3133 return; | 3225 return; |
3134 | 3226 |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3621 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; | 3713 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; |
3622 | 3714 |
3623 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. | 3715 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. |
3624 // Capture the error message in a crash key value. | 3716 // Capture the error message in a crash key value. |
3625 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); | 3717 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); |
3626 bad_message::ReceivedBadMessage(render_process_id, | 3718 bad_message::ReceivedBadMessage(render_process_id, |
3627 bad_message::RPH_MOJO_PROCESS_ERROR); | 3719 bad_message::RPH_MOJO_PROCESS_ERROR); |
3628 } | 3720 } |
3629 | 3721 |
3630 } // namespace content | 3722 } // namespace content |
OLD | NEW |