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

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

Issue 2857213005: PlzNavigate: implement process reuse for ServiceWorkers (Closed)
Patch Set: 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 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 url_loader_factory_binding_.Bind(std::move(loader_request)); 557 url_loader_factory_binding_.Bind(std::move(loader_request));
558 } 558 }
559 559
560 private: 560 private:
561 const int render_process_id_; 561 const int render_process_id_;
562 mojo::AssociatedBinding<mojom::URLLoaderFactory> url_loader_factory_binding_; 562 mojo::AssociatedBinding<mojom::URLLoaderFactory> url_loader_factory_binding_;
563 563
564 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_; 564 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
565 }; 565 };
566 566
567 // The following object is used to keep track of which sites
568 // RenderProcessHosts are hosting frames and expecting navigations to.
569 // There are two of them per BrowserContext, one for frames and one for
570 // navigations.
571 const void* const kFrameSiteCountPerProcessTrackerKey =
Charlie Reis 2017/05/15 03:41:52 I think pending and committed are probably better
clamy 2017/05/16 14:50:46 Done.
572 "FrameSiteCountPerProcessTrackerKey";
573 const void* const kNavigationSiteCountPerProcessTrackerKey =
574 "NavigationSiteCountPerProcessTrackerKey";
575 class SiteCountPerProcessTracker : public base::SupportsUserData::Data,
clamy 2017/05/04 16:01:01 This class + data structure looks a bit weird. Thi
nasko 2017/05/05 05:22:00 Yuck! Yet another reason to hate MockRenderProcess
Charlie Reis 2017/05/15 03:41:52 If we really want per-RPH state, we should find a
clamy 2017/05/15 15:21:15 This is how I had written it initially. However, w
Charlie Reis 2017/05/15 23:46:18 Interesting! Yes, I hadn't thought about the proc
clamy 2017/05/16 14:50:46 I've reversed the map as asked, and remove the obs
576 public RenderProcessHostObserver {
577 public:
578 SiteCountPerProcessTracker() {}
579 ~SiteCountPerProcessTracker() override {}
580
581 void AddCountForSiteForProcess(RenderProcessHost* render_process_host,
582 std::string site) {
nasko 2017/05/05 05:22:00 Why accept the site as a string and not a GURL?
clamy 2017/05/16 14:50:46 Done.
583 std::map<std::string, int>& counts_per_site = map_[render_process_host];
nasko 2017/05/05 05:22:00 I assume you are using operator[] intentionally he
clamy 2017/05/05 15:10:11 Yes. We want to create one if we don't have one, a
584 if (counts_per_site.empty())
585 render_process_host->AddObserver(this);
586 ++counts_per_site[site];
587 }
588
589 void RemoveCountForSiteForProcess(RenderProcessHost* render_process_host,
590 std::string site) {
591 std::map<std::string, int>& counts_per_site = map_[render_process_host];
nasko 2017/05/05 05:22:00 Shouldn't this be map_.find()?
clamy 2017/05/16 14:50:46 Done.
592 --counts_per_site[site];
593 DCHECK(counts_per_site[site] >= 0);
594 if (counts_per_site[site] == 0)
595 counts_per_site.erase(site);
596 if (counts_per_site.empty()) {
597 map_.erase(render_process_host);
598 render_process_host->RemoveObserver(this);
599 }
600 }
601
602 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
603 map_.erase(host);
604 }
605
606 void FindRenderProcessesForSite(
607 std::string site,
608 std::set<RenderProcessHost*>* foreground_processes,
609 std::set<RenderProcessHost*>* background_processes) {
610 for (auto site_counts_per_process : map_) {
611 if (site_counts_per_process.second.count(site) > 0) {
612 RenderProcessHost* host = site_counts_per_process.first;
613 if (host->VisibleWidgetCount())
614 foreground_processes->insert(host);
615 else
616 background_processes->insert(host);
617 }
618 }
619 }
620
621 private:
622 using SiteCountPerProcessMap =
623 std::map<RenderProcessHost*, std::map<std::string, int>>;
624 SiteCountPerProcessMap map_;
625 };
626
567 } // namespace 627 } // namespace
568 628
569 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; 629 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
570 630
571 base::MessageLoop* g_in_process_thread; 631 base::MessageLoop* g_in_process_thread;
572 632
573 // Stores the maximum number of renderer processes the content module can 633 // Stores the maximum number of renderer processes the content module can
574 // create. 634 // create.
575 static size_t g_max_renderer_count_override = 0; 635 static size_t g_max_renderer_count_override = 0;
576 636
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1677 DCHECK_GT(audio_stream_count_, 0); 1737 DCHECK_GT(audio_stream_count_, 0);
1678 --audio_stream_count_; 1738 --audio_stream_count_;
1679 UpdateProcessPriority(); 1739 UpdateProcessPriority();
1680 } 1740 }
1681 1741
1682 void RenderProcessHostImpl::set_render_process_host_factory( 1742 void RenderProcessHostImpl::set_render_process_host_factory(
1683 const RenderProcessHostFactory* rph_factory) { 1743 const RenderProcessHostFactory* rph_factory) {
1684 g_render_process_host_factory_ = rph_factory; 1744 g_render_process_host_factory_ = rph_factory;
1685 } 1745 }
1686 1746
1747 // static
1748 void RenderProcessHostImpl::AddFrameWithSite(
1749 BrowserContext* browser_context,
1750 RenderProcessHost* render_process_host,
1751 const GURL& site_url) {
1752 std::string site = SiteInstance::GetSiteForURL(browser_context, site_url)
1753 .possibly_invalid_spec();
nasko 2017/05/05 05:22:00 Why possibly_invalid_spec()? Shouldn't an non-empt
clamy 2017/05/16 14:50:46 It's now taking a GURL.
1754 if (site.empty())
1755 return;
1756
1757 SiteCountPerProcessTracker* tracker =
1758 static_cast<SiteCountPerProcessTracker*>(
1759 browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey));
1760 if (!tracker) {
1761 tracker = new SiteCountPerProcessTracker();
1762 browser_context->SetUserData(kFrameSiteCountPerProcessTrackerKey,
1763 base::WrapUnique(tracker));
1764 }
1765 tracker->AddCountForSiteForProcess(render_process_host, site);
1766 }
1767
1768 // static
1769 void RenderProcessHostImpl::RemoveFrameWithSite(
1770 BrowserContext* browser_context,
1771 RenderProcessHost* render_process_host,
1772 const GURL& site_url) {
1773 std::string site = SiteInstance::GetSiteForURL(browser_context, site_url)
1774 .possibly_invalid_spec();
1775 if (site.empty())
1776 return;
1777
1778 SiteCountPerProcessTracker* tracker =
1779 static_cast<SiteCountPerProcessTracker*>(
1780 browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey));
1781 if (!tracker) {
1782 tracker = new SiteCountPerProcessTracker();
1783 browser_context->SetUserData(kFrameSiteCountPerProcessTrackerKey,
1784 base::WrapUnique(tracker));
1785 }
1786 tracker->RemoveCountForSiteForProcess(render_process_host, site);
1787 }
1788
1789 // static
1790 void RenderProcessHostImpl::AddExpectedNavigationToSite(
1791 BrowserContext* browser_context,
1792 RenderProcessHost* render_process_host,
1793 const GURL& site_url) {
1794 std::string site = SiteInstance::GetSiteForURL(browser_context, site_url)
1795 .possibly_invalid_spec();
1796 if (site.empty())
1797 return;
1798
1799 SiteCountPerProcessTracker* tracker =
1800 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData(
1801 kNavigationSiteCountPerProcessTrackerKey));
1802 if (!tracker) {
1803 tracker = new SiteCountPerProcessTracker();
1804 browser_context->SetUserData(kNavigationSiteCountPerProcessTrackerKey,
1805 base::WrapUnique(tracker));
1806 }
1807 tracker->AddCountForSiteForProcess(render_process_host, site);
1808 }
1809
1810 // static
1811 void RenderProcessHostImpl::RemoveExpectedNavigationToSite(
1812 BrowserContext* browser_context,
1813 RenderProcessHost* render_process_host,
1814 const GURL& site_url) {
1815 std::string site = SiteInstance::GetSiteForURL(browser_context, site_url)
1816 .possibly_invalid_spec();
1817 if (site.empty())
1818 return;
1819
1820 SiteCountPerProcessTracker* tracker =
1821 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData(
1822 kNavigationSiteCountPerProcessTrackerKey));
1823 if (!tracker) {
1824 tracker = new SiteCountPerProcessTracker();
1825 browser_context->SetUserData(kNavigationSiteCountPerProcessTrackerKey,
1826 base::WrapUnique(tracker));
1827 }
1828 tracker->RemoveCountForSiteForProcess(render_process_host, site);
1829 }
1830
1687 bool RenderProcessHostImpl::IsForGuestsOnly() const { 1831 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1688 return is_for_guests_only_; 1832 return is_for_guests_only_;
1689 } 1833 }
1690 1834
1691 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 1835 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1692 return storage_partition_impl_; 1836 return storage_partition_impl_;
1693 } 1837 }
1694 1838
1695 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 1839 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1696 command_line->AppendSwitchASCII( 1840 command_line->AppendSwitchASCII(
(...skipping 1092 matching lines...) Expand 10 before | Expand all | Expand 10 after
2789 2933
2790 // First, attempt to reuse an existing RenderProcessHost if necessary. 2934 // First, attempt to reuse an existing RenderProcessHost if necessary.
2791 switch (process_reuse_policy) { 2935 switch (process_reuse_policy) {
2792 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: 2936 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE:
2793 render_process_host = GetProcessHostForSite(browser_context, site_url); 2937 render_process_host = GetProcessHostForSite(browser_context, site_url);
2794 break; 2938 break;
2795 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: 2939 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS:
2796 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); 2940 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
2797 render_process_host = 2941 render_process_host =
2798 GetDefaultSubframeProcessHost(browser_context, site_instance); 2942 GetDefaultSubframeProcessHost(browser_context, site_instance);
2943 case SiteInstanceImpl::ProcessReusePolicy::
2944 REUSE_CHECKING_FRAMES_AND_NAVIGATIONS:
2945 render_process_host =
2946 FindReusableProcessHostForSite(browser_context, site_url);
2799 break; 2947 break;
2800 default: 2948 default:
2801 break; 2949 break;
2802 } 2950 }
2803 2951
2804 // If not (or if none found), see if we should reuse an existing process. 2952 // If not (or if none found), see if we should reuse an existing process.
2805 if (!render_process_host && 2953 if (!render_process_host &&
2806 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 2954 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
2807 render_process_host = GetExistingProcessHost(browser_context, site_url); 2955 render_process_host = GetExistingProcessHost(browser_context, site_url);
2808 } 2956 }
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); 3309 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
3162 if (!holder) { 3310 if (!holder) {
3163 holder = new DefaultSubframeProcessHostHolder(browser_context); 3311 holder = new DefaultSubframeProcessHostHolder(browser_context);
3164 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, 3312 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
3165 base::WrapUnique(holder)); 3313 base::WrapUnique(holder));
3166 } 3314 }
3167 3315
3168 return holder->GetProcessHost(site_instance); 3316 return holder->GetProcessHost(site_instance);
3169 } 3317 }
3170 3318
3319 // static
3320 RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
3321 BrowserContext* browser_context,
3322 const GURL& site_url) {
3323 std::string site = SiteInstance::GetSiteForURL(browser_context, site_url)
3324 .possibly_invalid_spec();
3325 if (site.empty())
3326 return nullptr;
3327
3328 std::set<RenderProcessHost*> eligible_foreground_hosts;
3329 std::set<RenderProcessHost*> eligible_background_hosts;
3330
3331 // Add the RenderProcessHosts hosting a frame rendering site to the list of
nasko 2017/05/05 05:22:00 nit: "... hosting a frame for |site| to ..."
clamy 2017/05/16 14:50:46 Done.
3332 // eligible RenderProcessHosts.
3333 SiteCountPerProcessTracker* frame_tracker =
3334 static_cast<SiteCountPerProcessTracker*>(
3335 browser_context->GetUserData(kFrameSiteCountPerProcessTrackerKey));
3336 if (frame_tracker) {
3337 frame_tracker->FindRenderProcessesForSite(site, &eligible_foreground_hosts,
3338 &eligible_background_hosts);
3339 }
3340
3341 // Add the RenderProcessHosts expecting a navigation to site to the list of
3342 // eligible RenderProcessHosts.
3343 SiteCountPerProcessTracker* navigation_tracker =
clamy 2017/05/04 16:01:01 if we want to implement process-per-site using thi
3344 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData(
3345 kNavigationSiteCountPerProcessTrackerKey));
3346 if (frame_tracker) {
3347 navigation_tracker->FindRenderProcessesForSite(
3348 site, &eligible_foreground_hosts, &eligible_background_hosts);
3349 }
3350
3351 if (!eligible_foreground_hosts.empty()) {
3352 int index = rand() % eligible_foreground_hosts.size();
nasko 2017/05/05 05:22:00 base::RandInt
clamy 2017/05/16 14:50:46 Done.
3353 auto iterator = eligible_foreground_hosts.begin();
3354 for (int i = 0; i < index; ++i)
3355 ++iterator;
3356 return (*iterator);
3357 }
3358
3359 if (!eligible_background_hosts.empty()) {
3360 int index = rand() % eligible_background_hosts.size();
nasko 2017/05/05 05:22:00 base::RandInt
clamy 2017/05/16 14:50:46 Done.
3361 auto iterator = eligible_background_hosts.begin();
3362 for (int i = 0; i < index; ++i)
3363 ++iterator;
3364 return (*iterator);
3365 }
3366
3367 return nullptr;
3368 }
3369
3171 #if BUILDFLAG(ENABLE_WEBRTC) 3370 #if BUILDFLAG(ENABLE_WEBRTC)
3172 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { 3371 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
3173 BrowserThread::PostTask( 3372 BrowserThread::PostTask(
3174 BrowserThread::UI, FROM_HERE, 3373 BrowserThread::UI, FROM_HERE,
3175 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, 3374 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
3176 weak_factory_.GetWeakPtr(), id)); 3375 weak_factory_.GetWeakPtr(), id));
3177 } 3376 }
3178 3377
3179 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { 3378 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
3180 BrowserThread::PostTask( 3379 BrowserThread::PostTask(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3251 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3450 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3252 3451
3253 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3452 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3254 // Capture the error message in a crash key value. 3453 // Capture the error message in a crash key value.
3255 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3454 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3256 bad_message::ReceivedBadMessage(render_process_id, 3455 bad_message::ReceivedBadMessage(render_process_id,
3257 bad_message::RPH_MOJO_PROCESS_ERROR); 3456 bad_message::RPH_MOJO_PROCESS_ERROR);
3258 } 3457 }
3259 3458
3260 } // namespace content 3459 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698