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

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

Issue 2857213005: PlzNavigate: implement process reuse for ServiceWorkers (Closed)
Patch Set: Addressed comments Created 3 years, 7 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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 delete this; 622 delete this;
623 } 623 }
624 624
625 RenderProcessHost* render_process_host_; 625 RenderProcessHost* render_process_host_;
626 base::OnceClosure task_; 626 base::OnceClosure task_;
627 base::WeakPtrFactory<RenderProcessHostIsReadyObserver> weak_factory_; 627 base::WeakPtrFactory<RenderProcessHostIsReadyObserver> weak_factory_;
628 628
629 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostIsReadyObserver); 629 DISALLOW_COPY_AND_ASSIGN(RenderProcessHostIsReadyObserver);
630 }; 630 };
631 631
632 // The following class is used to track the sites each RenderProcessHost is
633 // hosting frames for and expecting navigations to. There are two of them per
634 // BrowserContext: one for frames and one for navigations.
635 //
636 // For each site, the SiteProcessCountTracker keeps a map of counts per
637 // RenderProcessHost, which represents the number of frames/navigations
638 // for this site that are associated with the RenderProcessHost. This allows to
639 // quickly lookup a list of RenderProcessHost that can be used by a particular
640 // SiteInstance. On the other hand, it does not allow to quickly lookup which
641 // sites are hosted by a RenderProcessHost. This class is meant to help reusing
642 // RenderProcessHosts among SiteInstances, not to perform security checks for a
643 // RenderProcessHost.
644 const void* const kCommittedSiteProcessCountTrackerKey =
645 "CommittedSiteProcessCountTrackerKey";
646 const void* const kPendingSiteProcessCountTrackerKey =
647 "PendingSiteProcessCountTrackerKey";
648 class SiteProcessCountTracker : public base::SupportsUserData::Data {
649 public:
650 SiteProcessCountTracker() {}
651 ~SiteProcessCountTracker() override {}
652
653 void IncrementSiteProcessCount(const GURL& site_url,
654 int render_process_host_id) {
655 std::map<ProcessID, Count>& counts_per_process = map_[site_url];
656 ++counts_per_process[render_process_host_id];
657 }
658
659 void DecrementSiteProcessCount(const GURL& site_url,
660 int render_process_host_id) {
661 auto result = map_.find(site_url);
662 DCHECK(result != map_.end());
663 std::map<ProcessID, Count>& counts_per_process = result->second;
664
665 --counts_per_process[render_process_host_id];
666 DCHECK(counts_per_process[render_process_host_id] >= 0);
667
668 if (counts_per_process[render_process_host_id] == 0)
669 counts_per_process.erase(render_process_host_id);
670
671 if (counts_per_process.empty())
672 map_.erase(site_url);
673 }
674
675 void FindRenderProcessesForSite(
676 const GURL& site_url,
677 std::set<RenderProcessHost*>* foreground_processes,
678 std::set<RenderProcessHost*>* background_processes) {
679 auto result = map_.find(site_url);
680 if (result == map_.end())
681 return;
682
683 std::map<ProcessID, Count>& counts_per_process = result->second;
684 for (auto iter : counts_per_process) {
685 RenderProcessHost* host = RenderProcessHost::FromID(iter.first);
686 DCHECK(host);
687 if (host->VisibleWidgetCount())
688 foreground_processes->insert(host);
689 else
690 background_processes->insert(host);
691 }
692 }
693
694 private:
695 using ProcessID = int;
696 using Count = int;
697 using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>;
698 CountPerProcessPerSiteMap map_;
699 };
700
632 } // namespace 701 } // namespace
633 702
634 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; 703 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
635 704
636 base::MessageLoop* g_in_process_thread; 705 base::MessageLoop* g_in_process_thread;
637 706
638 // Stores the maximum number of renderer processes the content module can 707 // Stores the maximum number of renderer processes the content module can
639 // create. 708 // create.
640 static size_t g_max_renderer_count_override = 0; 709 static size_t g_max_renderer_count_override = 0;
641 710
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 DCHECK_GT(audio_stream_count_, 0); 1810 DCHECK_GT(audio_stream_count_, 0);
1742 --audio_stream_count_; 1811 --audio_stream_count_;
1743 UpdateProcessPriority(); 1812 UpdateProcessPriority();
1744 } 1813 }
1745 1814
1746 void RenderProcessHostImpl::set_render_process_host_factory( 1815 void RenderProcessHostImpl::set_render_process_host_factory(
1747 const RenderProcessHostFactory* rph_factory) { 1816 const RenderProcessHostFactory* rph_factory) {
1748 g_render_process_host_factory_ = rph_factory; 1817 g_render_process_host_factory_ = rph_factory;
1749 } 1818 }
1750 1819
1820 // static
1821 void RenderProcessHostImpl::AddFrameWithSite(
1822 BrowserContext* browser_context,
1823 RenderProcessHost* render_process_host,
1824 const GURL& site_url) {
1825 if (site_url.is_empty())
1826 return;
1827
1828 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1829 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1830 if (!tracker) {
1831 tracker = new SiteProcessCountTracker();
1832 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1833 base::WrapUnique(tracker));
1834 }
1835 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1836 }
1837
1838 // static
1839 void RenderProcessHostImpl::RemoveFrameWithSite(
1840 BrowserContext* browser_context,
1841 RenderProcessHost* render_process_host,
1842 const GURL& site_url) {
1843 if (site_url.is_empty())
1844 return;
1845
1846 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1847 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1848 if (!tracker) {
1849 tracker = new SiteProcessCountTracker();
1850 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1851 base::WrapUnique(tracker));
1852 }
1853 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1854 }
1855
1856 // static
1857 void RenderProcessHostImpl::AddExpectedNavigationToSite(
1858 BrowserContext* browser_context,
1859 RenderProcessHost* render_process_host,
1860 const GURL& site_url) {
1861 if (site_url.is_empty())
1862 return;
1863
1864 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1865 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1866 if (!tracker) {
1867 tracker = new SiteProcessCountTracker();
1868 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1869 base::WrapUnique(tracker));
1870 }
1871 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1872 }
1873
1874 // static
1875 void RenderProcessHostImpl::RemoveExpectedNavigationToSite(
1876 BrowserContext* browser_context,
1877 RenderProcessHost* render_process_host,
1878 const GURL& site_url) {
1879 if (site_url.is_empty())
1880 return;
1881
1882 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1883 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1884 if (!tracker) {
1885 tracker = new SiteProcessCountTracker();
1886 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1887 base::WrapUnique(tracker));
1888 }
1889 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1890 }
1891
1751 bool RenderProcessHostImpl::IsForGuestsOnly() const { 1892 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1752 return is_for_guests_only_; 1893 return is_for_guests_only_;
1753 } 1894 }
1754 1895
1755 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 1896 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1756 return storage_partition_impl_; 1897 return storage_partition_impl_;
1757 } 1898 }
1758 1899
1759 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 1900 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1760 command_line->AppendSwitchASCII( 1901 command_line->AppendSwitchASCII(
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2866 // First, attempt to reuse an existing RenderProcessHost if necessary. 3007 // First, attempt to reuse an existing RenderProcessHost if necessary.
2867 switch (process_reuse_policy) { 3008 switch (process_reuse_policy) {
2868 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: 3009 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE:
2869 render_process_host = GetProcessHostForSite(browser_context, site_url); 3010 render_process_host = GetProcessHostForSite(browser_context, site_url);
2870 break; 3011 break;
2871 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: 3012 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS:
2872 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); 3013 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
2873 render_process_host = GetDefaultSubframeProcessHost( 3014 render_process_host = GetDefaultSubframeProcessHost(
2874 browser_context, site_instance, is_for_guests_only); 3015 browser_context, site_instance, is_for_guests_only);
2875 break; 3016 break;
3017 case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
3018 render_process_host =
3019 FindReusableProcessHostForSite(browser_context, site_url);
3020 break;
2876 default: 3021 default:
2877 break; 3022 break;
2878 } 3023 }
2879 3024
2880 // If not (or if none found), see if we should reuse an existing process. 3025 // If not (or if none found), see if we should reuse an existing process.
2881 if (!render_process_host && 3026 if (!render_process_host &&
2882 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3027 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
2883 render_process_host = GetExistingProcessHost(browser_context, site_url); 3028 render_process_host = GetExistingProcessHost(browser_context, site_url);
2884 } 3029 }
2885 3030
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
3258 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); 3403 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
3259 if (!holder) { 3404 if (!holder) {
3260 holder = new DefaultSubframeProcessHostHolder(browser_context); 3405 holder = new DefaultSubframeProcessHostHolder(browser_context);
3261 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, 3406 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
3262 base::WrapUnique(holder)); 3407 base::WrapUnique(holder));
3263 } 3408 }
3264 3409
3265 return holder->GetProcessHost(site_instance, is_for_guests_only); 3410 return holder->GetProcessHost(site_instance, is_for_guests_only);
3266 } 3411 }
3267 3412
3413 // static
3414 RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
3415 BrowserContext* browser_context,
3416 const GURL& site_url) {
3417 if (site_url.is_empty())
3418 return nullptr;
3419
3420 std::set<RenderProcessHost*> eligible_foreground_hosts;
3421 std::set<RenderProcessHost*> eligible_background_hosts;
3422
3423 // First, add the RenderProcessHosts expecting a navigation to |site_url| to
3424 // the list of eligible RenderProcessHosts.
3425 SiteProcessCountTracker* pending_tracker =
3426 static_cast<SiteProcessCountTracker*>(
3427 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
3428 if (pending_tracker) {
3429 pending_tracker->FindRenderProcessesForSite(
3430 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3431 }
3432
3433 if (eligible_foreground_hosts.empty()) {
3434 // If needed, add the RenderProcessHosts hosting a frame for |site_url| to
3435 // the list of eligible RenderProcessHosts.
3436 SiteProcessCountTracker* committed_tracker =
3437 static_cast<SiteProcessCountTracker*>(
3438 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
3439 if (committed_tracker) {
3440 committed_tracker->FindRenderProcessesForSite(
3441 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3442 }
3443 }
3444
3445 if (!eligible_foreground_hosts.empty()) {
3446 int index = base::RandInt(0, eligible_foreground_hosts.size() - 1);
3447 auto iterator = eligible_foreground_hosts.begin();
3448 for (int i = 0; i < index; ++i)
3449 ++iterator;
3450 return (*iterator);
3451 }
3452
3453 if (!eligible_background_hosts.empty()) {
3454 int index = base::RandInt(0, eligible_background_hosts.size() - 1);
3455 auto iterator = eligible_background_hosts.begin();
3456 for (int i = 0; i < index; ++i)
3457 ++iterator;
3458 return (*iterator);
3459 }
3460
3461 return nullptr;
3462 }
3463
3268 #if BUILDFLAG(ENABLE_WEBRTC) 3464 #if BUILDFLAG(ENABLE_WEBRTC)
3269 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { 3465 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
3270 BrowserThread::PostTask( 3466 BrowserThread::PostTask(
3271 BrowserThread::UI, FROM_HERE, 3467 BrowserThread::UI, FROM_HERE,
3272 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, 3468 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
3273 weak_factory_.GetWeakPtr(), id)); 3469 weak_factory_.GetWeakPtr(), id));
3274 } 3470 }
3275 3471
3276 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { 3472 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
3277 BrowserThread::PostTask( 3473 BrowserThread::PostTask(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3348 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3544 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3349 3545
3350 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3546 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3351 // Capture the error message in a crash key value. 3547 // Capture the error message in a crash key value.
3352 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3548 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3353 bad_message::ReceivedBadMessage(render_process_id, 3549 bad_message::ReceivedBadMessage(render_process_id,
3354 bad_message::RPH_MOJO_PROCESS_ERROR); 3550 bad_message::RPH_MOJO_PROCESS_ERROR);
3355 } 3551 }
3356 3552
3357 } // namespace content 3553 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698