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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 object is used to keep track of which sites |
| 633 // RenderProcessHosts are hosting frames and expecting navigations to. |
| 634 // There are two of them per BrowserContext, one for frames and one for |
| 635 // navigations. |
| 636 const void* const kCommittedSiteCountPerProcessTrackerKey = |
| 637 "CommittedSiteCountPerProcessTrackerKey"; |
| 638 const void* const kPendingSiteCountPerProcessTrackerKey = |
| 639 "PendingSiteCountPerProcessTrackerKey"; |
| 640 class SiteCountPerProcessTracker : public base::SupportsUserData::Data { |
| 641 public: |
| 642 SiteCountPerProcessTracker() {} |
| 643 ~SiteCountPerProcessTracker() override {} |
| 644 |
| 645 void AddCountForSiteForProcess(int render_process_host_id, |
| 646 const GURL& site_url) { |
| 647 std::map<ProcessID, Count>& counts_per_process = map_[site_url]; |
| 648 ++counts_per_process[render_process_host_id]; |
| 649 } |
| 650 |
| 651 void RemoveCountForSiteForProcess(int render_process_host_id, |
| 652 const GURL& site_url) { |
| 653 auto result = map_.find(site_url); |
| 654 DCHECK(result != map_.end()); |
| 655 std::map<ProcessID, Count>& counts_per_process = result->second; |
| 656 |
| 657 --counts_per_process[render_process_host_id]; |
| 658 DCHECK(counts_per_process[render_process_host_id] >= 0); |
| 659 |
| 660 if (counts_per_process[render_process_host_id] == 0) |
| 661 counts_per_process.erase(render_process_host_id); |
| 662 |
| 663 if (counts_per_process.empty()) |
| 664 map_.erase(site_url); |
| 665 } |
| 666 |
| 667 void FindRenderProcessesForSite( |
| 668 const GURL& site_url, |
| 669 std::set<RenderProcessHost*>* foreground_processes, |
| 670 std::set<RenderProcessHost*>* background_processes) { |
| 671 auto result = map_.find(site_url); |
| 672 if (result == map_.end()) |
| 673 return; |
| 674 |
| 675 std::map<ProcessID, Count>& counts_per_process = result->second; |
| 676 for (auto iter : counts_per_process) { |
| 677 RenderProcessHost* host = RenderProcessHost::FromID(iter.first); |
| 678 DCHECK(host); |
| 679 if (host->VisibleWidgetCount()) |
| 680 foreground_processes->insert(host); |
| 681 else |
| 682 background_processes->insert(host); |
| 683 } |
| 684 } |
| 685 |
| 686 private: |
| 687 using ProcessID = int; |
| 688 using Count = int; |
| 689 using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>; |
| 690 CountPerProcessPerSiteMap map_; |
| 691 }; |
| 692 |
632 } // namespace | 693 } // namespace |
633 | 694 |
634 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; | 695 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; |
635 | 696 |
636 base::MessageLoop* g_in_process_thread; | 697 base::MessageLoop* g_in_process_thread; |
637 | 698 |
638 // Stores the maximum number of renderer processes the content module can | 699 // Stores the maximum number of renderer processes the content module can |
639 // create. | 700 // create. |
640 static size_t g_max_renderer_count_override = 0; | 701 static size_t g_max_renderer_count_override = 0; |
641 | 702 |
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 DCHECK_GT(audio_stream_count_, 0); | 1802 DCHECK_GT(audio_stream_count_, 0); |
1742 --audio_stream_count_; | 1803 --audio_stream_count_; |
1743 UpdateProcessPriority(); | 1804 UpdateProcessPriority(); |
1744 } | 1805 } |
1745 | 1806 |
1746 void RenderProcessHostImpl::set_render_process_host_factory( | 1807 void RenderProcessHostImpl::set_render_process_host_factory( |
1747 const RenderProcessHostFactory* rph_factory) { | 1808 const RenderProcessHostFactory* rph_factory) { |
1748 g_render_process_host_factory_ = rph_factory; | 1809 g_render_process_host_factory_ = rph_factory; |
1749 } | 1810 } |
1750 | 1811 |
| 1812 // static |
| 1813 void RenderProcessHostImpl::AddFrameWithSite( |
| 1814 BrowserContext* browser_context, |
| 1815 RenderProcessHost* render_process_host, |
| 1816 const GURL& site_url) { |
| 1817 if (site_url.is_empty()) |
| 1818 return; |
| 1819 |
| 1820 SiteCountPerProcessTracker* tracker = |
| 1821 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| 1822 kCommittedSiteCountPerProcessTrackerKey)); |
| 1823 if (!tracker) { |
| 1824 tracker = new SiteCountPerProcessTracker(); |
| 1825 browser_context->SetUserData(kCommittedSiteCountPerProcessTrackerKey, |
| 1826 base::WrapUnique(tracker)); |
| 1827 } |
| 1828 tracker->AddCountForSiteForProcess(render_process_host->GetID(), site_url); |
| 1829 } |
| 1830 |
| 1831 // static |
| 1832 void RenderProcessHostImpl::RemoveFrameWithSite( |
| 1833 BrowserContext* browser_context, |
| 1834 RenderProcessHost* render_process_host, |
| 1835 const GURL& site_url) { |
| 1836 if (site_url.is_empty()) |
| 1837 return; |
| 1838 |
| 1839 SiteCountPerProcessTracker* tracker = |
| 1840 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| 1841 kCommittedSiteCountPerProcessTrackerKey)); |
| 1842 if (!tracker) { |
| 1843 tracker = new SiteCountPerProcessTracker(); |
| 1844 browser_context->SetUserData(kCommittedSiteCountPerProcessTrackerKey, |
| 1845 base::WrapUnique(tracker)); |
| 1846 } |
| 1847 tracker->RemoveCountForSiteForProcess(render_process_host->GetID(), site_url); |
| 1848 } |
| 1849 |
| 1850 // static |
| 1851 void RenderProcessHostImpl::AddExpectedNavigationToSite( |
| 1852 BrowserContext* browser_context, |
| 1853 RenderProcessHost* render_process_host, |
| 1854 const GURL& site_url) { |
| 1855 if (site_url.is_empty()) |
| 1856 return; |
| 1857 |
| 1858 SiteCountPerProcessTracker* tracker = |
| 1859 static_cast<SiteCountPerProcessTracker*>( |
| 1860 browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
| 1861 if (!tracker) { |
| 1862 tracker = new SiteCountPerProcessTracker(); |
| 1863 browser_context->SetUserData(kPendingSiteCountPerProcessTrackerKey, |
| 1864 base::WrapUnique(tracker)); |
| 1865 } |
| 1866 tracker->AddCountForSiteForProcess(render_process_host->GetID(), site_url); |
| 1867 } |
| 1868 |
| 1869 // static |
| 1870 void RenderProcessHostImpl::RemoveExpectedNavigationToSite( |
| 1871 BrowserContext* browser_context, |
| 1872 RenderProcessHost* render_process_host, |
| 1873 const GURL& site_url) { |
| 1874 if (site_url.is_empty()) |
| 1875 return; |
| 1876 |
| 1877 SiteCountPerProcessTracker* tracker = |
| 1878 static_cast<SiteCountPerProcessTracker*>( |
| 1879 browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
| 1880 if (!tracker) { |
| 1881 tracker = new SiteCountPerProcessTracker(); |
| 1882 browser_context->SetUserData(kPendingSiteCountPerProcessTrackerKey, |
| 1883 base::WrapUnique(tracker)); |
| 1884 } |
| 1885 tracker->RemoveCountForSiteForProcess(render_process_host->GetID(), site_url); |
| 1886 } |
| 1887 |
1751 bool RenderProcessHostImpl::IsForGuestsOnly() const { | 1888 bool RenderProcessHostImpl::IsForGuestsOnly() const { |
1752 return is_for_guests_only_; | 1889 return is_for_guests_only_; |
1753 } | 1890 } |
1754 | 1891 |
1755 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { | 1892 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { |
1756 return storage_partition_impl_; | 1893 return storage_partition_impl_; |
1757 } | 1894 } |
1758 | 1895 |
1759 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { | 1896 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { |
1760 command_line->AppendSwitchASCII( | 1897 command_line->AppendSwitchASCII( |
(...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2857 | 2994 |
2858 // First, attempt to reuse an existing RenderProcessHost if necessary. | 2995 // First, attempt to reuse an existing RenderProcessHost if necessary. |
2859 switch (process_reuse_policy) { | 2996 switch (process_reuse_policy) { |
2860 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: | 2997 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: |
2861 render_process_host = GetProcessHostForSite(browser_context, site_url); | 2998 render_process_host = GetProcessHostForSite(browser_context, site_url); |
2862 break; | 2999 break; |
2863 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: | 3000 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: |
2864 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); | 3001 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); |
2865 render_process_host = GetDefaultSubframeProcessHost( | 3002 render_process_host = GetDefaultSubframeProcessHost( |
2866 browser_context, site_instance, is_for_guests_only); | 3003 browser_context, site_instance, is_for_guests_only); |
| 3004 case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE: |
| 3005 render_process_host = |
| 3006 FindReusableProcessHostForSite(browser_context, site_url); |
2867 break; | 3007 break; |
2868 default: | 3008 default: |
2869 break; | 3009 break; |
2870 } | 3010 } |
2871 | 3011 |
2872 // If not (or if none found), see if we should reuse an existing process. | 3012 // If not (or if none found), see if we should reuse an existing process. |
2873 if (!render_process_host && | 3013 if (!render_process_host && |
2874 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { | 3014 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { |
2875 render_process_host = GetExistingProcessHost(browser_context, site_url); | 3015 render_process_host = GetExistingProcessHost(browser_context, site_url); |
2876 } | 3016 } |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3250 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); | 3390 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); |
3251 if (!holder) { | 3391 if (!holder) { |
3252 holder = new DefaultSubframeProcessHostHolder(browser_context); | 3392 holder = new DefaultSubframeProcessHostHolder(browser_context); |
3253 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, | 3393 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, |
3254 base::WrapUnique(holder)); | 3394 base::WrapUnique(holder)); |
3255 } | 3395 } |
3256 | 3396 |
3257 return holder->GetProcessHost(site_instance, is_for_guests_only); | 3397 return holder->GetProcessHost(site_instance, is_for_guests_only); |
3258 } | 3398 } |
3259 | 3399 |
| 3400 // static |
| 3401 RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite( |
| 3402 BrowserContext* browser_context, |
| 3403 const GURL& site_url) { |
| 3404 if (site_url.is_empty()) |
| 3405 return nullptr; |
| 3406 |
| 3407 std::set<RenderProcessHost*> eligible_foreground_hosts; |
| 3408 std::set<RenderProcessHost*> eligible_background_hosts; |
| 3409 |
| 3410 // Add the RenderProcessHosts hosting a frame for |site_url| to the list of |
| 3411 // eligible RenderProcessHosts. |
| 3412 SiteCountPerProcessTracker* committed_tracker = |
| 3413 static_cast<SiteCountPerProcessTracker*>(browser_context->GetUserData( |
| 3414 kCommittedSiteCountPerProcessTrackerKey)); |
| 3415 if (committed_tracker) { |
| 3416 committed_tracker->FindRenderProcessesForSite( |
| 3417 site_url, &eligible_foreground_hosts, &eligible_background_hosts); |
| 3418 } |
| 3419 |
| 3420 // Add the RenderProcessHosts expecting a navigation to |site_url| to the list |
| 3421 // of eligible RenderProcessHosts. |
| 3422 SiteCountPerProcessTracker* pending_tracker = |
| 3423 static_cast<SiteCountPerProcessTracker*>( |
| 3424 browser_context->GetUserData(kPendingSiteCountPerProcessTrackerKey)); |
| 3425 if (pending_tracker) { |
| 3426 pending_tracker->FindRenderProcessesForSite( |
| 3427 site_url, &eligible_foreground_hosts, &eligible_background_hosts); |
| 3428 } |
| 3429 |
| 3430 if (!eligible_foreground_hosts.empty()) { |
| 3431 int index = base::RandInt(0, eligible_foreground_hosts.size() - 1); |
| 3432 auto iterator = eligible_foreground_hosts.begin(); |
| 3433 for (int i = 0; i < index; ++i) |
| 3434 ++iterator; |
| 3435 return (*iterator); |
| 3436 } |
| 3437 |
| 3438 if (!eligible_background_hosts.empty()) { |
| 3439 int index = base::RandInt(0, eligible_background_hosts.size() - 1); |
| 3440 auto iterator = eligible_background_hosts.begin(); |
| 3441 for (int i = 0; i < index; ++i) |
| 3442 ++iterator; |
| 3443 return (*iterator); |
| 3444 } |
| 3445 |
| 3446 return nullptr; |
| 3447 } |
| 3448 |
3260 #if BUILDFLAG(ENABLE_WEBRTC) | 3449 #if BUILDFLAG(ENABLE_WEBRTC) |
3261 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { | 3450 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { |
3262 BrowserThread::PostTask( | 3451 BrowserThread::PostTask( |
3263 BrowserThread::UI, FROM_HERE, | 3452 BrowserThread::UI, FROM_HERE, |
3264 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, | 3453 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, |
3265 weak_factory_.GetWeakPtr(), id)); | 3454 weak_factory_.GetWeakPtr(), id)); |
3266 } | 3455 } |
3267 | 3456 |
3268 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { | 3457 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { |
3269 BrowserThread::PostTask( | 3458 BrowserThread::PostTask( |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3340 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; | 3529 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; |
3341 | 3530 |
3342 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. | 3531 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. |
3343 // Capture the error message in a crash key value. | 3532 // Capture the error message in a crash key value. |
3344 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); | 3533 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); |
3345 bad_message::ReceivedBadMessage(render_process_id, | 3534 bad_message::ReceivedBadMessage(render_process_id, |
3346 bad_message::RPH_MOJO_PROCESS_ERROR); | 3535 bad_message::RPH_MOJO_PROCESS_ERROR); |
3347 } | 3536 } |
3348 | 3537 |
3349 } // namespace content | 3538 } // namespace content |
OLD | NEW |