Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: content/browser/renderer_host/render_process_host_impl.cc

Issue 2929113002: Enable spare RenderProcessHost to be preinitialized. (Closed)
Patch Set: remove race from test Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698