Chromium Code Reviews| 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 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |