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

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

Issue 2857213005: PlzNavigate: implement process reuse for ServiceWorkers (Closed)
Patch Set: Removed wrong CleanupNavigation call 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 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 RenderProcessHostObserver {
650 public:
651 SiteProcessCountTracker() {}
652 ~SiteProcessCountTracker() override { DCHECK(map_.empty()); }
653
654 void IncrementSiteProcessCount(const GURL& site_url,
655 int render_process_host_id) {
656 std::map<ProcessID, Count>& counts_per_process = map_[site_url];
657 ++counts_per_process[render_process_host_id];
658
659 #ifndef NDEBUG
660 // In tests, observer the RenderProcessHost destrcution, to check that it is
Charlie Reis 2017/05/24 17:18:37 nit: s/tests/debug builds/ nit: observe nit: destr
clamy 2017/05/24 18:03:04 Done.
661 // properly removed from the map.
662 RenderProcessHost* host = RenderProcessHost::FromID(render_process_host_id);
663 if (!HasProcess(host))
664 host->AddObserver(this);
665 #endif
666 }
667
668 void DecrementSiteProcessCount(const GURL& site_url,
669 int render_process_host_id) {
670 auto result = map_.find(site_url);
671 DCHECK(result != map_.end());
672 std::map<ProcessID, Count>& counts_per_process = result->second;
673
674 --counts_per_process[render_process_host_id];
675 DCHECK(counts_per_process[render_process_host_id] >= 0);
676
677 if (counts_per_process[render_process_host_id] == 0)
678 counts_per_process.erase(render_process_host_id);
679
680 if (counts_per_process.empty())
681 map_.erase(site_url);
682 }
683
684 void FindRenderProcessesForSite(
685 const GURL& site_url,
686 std::set<RenderProcessHost*>* foreground_processes,
687 std::set<RenderProcessHost*>* background_processes) {
688 auto result = map_.find(site_url);
689 if (result == map_.end())
690 return;
691
692 std::map<ProcessID, Count>& counts_per_process = result->second;
693 for (auto iter : counts_per_process) {
694 RenderProcessHost* host = RenderProcessHost::FromID(iter.first);
695 DCHECK(host);
696 if (host->VisibleWidgetCount())
697 foreground_processes->insert(host);
698 else
699 background_processes->insert(host);
700 }
701 }
702
703 private:
704 void RenderProcessHostDestroyed(RenderProcessHost* host) override {
705 host->RemoveObserver(this);
Charlie Reis 2017/05/24 17:18:37 Shouldn't this be within the ifndef as well? We o
clamy 2017/05/24 18:03:04 Done.
706 #ifndef NDEBUG
707 DCHECK(!HasProcess(host));
708 #endif
709 }
710
711 // Used in tests to ensure that RenderProcessHost don't persist in the map
Charlie Reis 2017/05/24 17:18:37 nit: s/tests/debug builds/
clamy 2017/05/24 18:03:04 Done.
712 // after they've been destroyed.
713 bool HasProcess(RenderProcessHost* process) {
Charlie Reis 2017/05/24 17:18:37 I'd include this in the ifndef as well, given the
clamy 2017/05/24 18:03:04 Done.
714 for (auto iter : map_) {
715 std::map<ProcessID, Count>& counts_per_process = iter.second;
716 for (auto iter_process : counts_per_process) {
717 if (iter_process.first == process->GetID())
718 return true;
719 }
720 }
721 return false;
722 }
723
724 using ProcessID = int;
725 using Count = int;
726 using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>;
727 CountPerProcessPerSiteMap map_;
728 };
729
632 } // namespace 730 } // namespace
633 731
634 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; 732 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
635 733
636 base::MessageLoop* g_in_process_thread; 734 base::MessageLoop* g_in_process_thread;
637 735
638 // Stores the maximum number of renderer processes the content module can 736 // Stores the maximum number of renderer processes the content module can
639 // create. 737 // create.
640 static size_t g_max_renderer_count_override = 0; 738 static size_t g_max_renderer_count_override = 0;
641 739
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 DCHECK_GT(audio_stream_count_, 0); 1839 DCHECK_GT(audio_stream_count_, 0);
1742 --audio_stream_count_; 1840 --audio_stream_count_;
1743 UpdateProcessPriority(); 1841 UpdateProcessPriority();
1744 } 1842 }
1745 1843
1746 void RenderProcessHostImpl::set_render_process_host_factory( 1844 void RenderProcessHostImpl::set_render_process_host_factory(
1747 const RenderProcessHostFactory* rph_factory) { 1845 const RenderProcessHostFactory* rph_factory) {
1748 g_render_process_host_factory_ = rph_factory; 1846 g_render_process_host_factory_ = rph_factory;
1749 } 1847 }
1750 1848
1849 // static
1850 void RenderProcessHostImpl::AddFrameWithSite(
1851 BrowserContext* browser_context,
1852 RenderProcessHost* render_process_host,
1853 const GURL& site_url) {
1854 if (site_url.is_empty())
1855 return;
1856
1857 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1858 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1859 if (!tracker) {
1860 tracker = new SiteProcessCountTracker();
1861 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1862 base::WrapUnique(tracker));
1863 }
1864 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1865 }
1866
1867 // static
1868 void RenderProcessHostImpl::RemoveFrameWithSite(
1869 BrowserContext* browser_context,
1870 RenderProcessHost* render_process_host,
1871 const GURL& site_url) {
1872 if (site_url.is_empty())
1873 return;
1874
1875 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1876 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1877 if (!tracker) {
1878 tracker = new SiteProcessCountTracker();
1879 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1880 base::WrapUnique(tracker));
1881 }
1882 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1883 }
1884
1885 // static
1886 void RenderProcessHostImpl::AddExpectedNavigationToSite(
1887 BrowserContext* browser_context,
1888 RenderProcessHost* render_process_host,
1889 const GURL& site_url) {
1890 if (site_url.is_empty())
1891 return;
1892
1893 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1894 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1895 if (!tracker) {
1896 tracker = new SiteProcessCountTracker();
1897 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1898 base::WrapUnique(tracker));
1899 }
1900 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1901 }
1902
1903 // static
1904 void RenderProcessHostImpl::RemoveExpectedNavigationToSite(
1905 BrowserContext* browser_context,
1906 RenderProcessHost* render_process_host,
1907 const GURL& site_url) {
1908 if (site_url.is_empty())
1909 return;
1910
1911 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1912 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1913 if (!tracker) {
1914 tracker = new SiteProcessCountTracker();
1915 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1916 base::WrapUnique(tracker));
1917 }
1918 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1919 }
1920
1751 bool RenderProcessHostImpl::IsForGuestsOnly() const { 1921 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1752 return is_for_guests_only_; 1922 return is_for_guests_only_;
1753 } 1923 }
1754 1924
1755 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 1925 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1756 return storage_partition_impl_; 1926 return storage_partition_impl_;
1757 } 1927 }
1758 1928
1759 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 1929 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1760 command_line->AppendSwitchASCII( 1930 command_line->AppendSwitchASCII(
(...skipping 1106 matching lines...) Expand 10 before | Expand all | Expand 10 after
2867 // First, attempt to reuse an existing RenderProcessHost if necessary. 3037 // First, attempt to reuse an existing RenderProcessHost if necessary.
2868 switch (process_reuse_policy) { 3038 switch (process_reuse_policy) {
2869 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: 3039 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE:
2870 render_process_host = GetProcessHostForSite(browser_context, site_url); 3040 render_process_host = GetProcessHostForSite(browser_context, site_url);
2871 break; 3041 break;
2872 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: 3042 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS:
2873 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); 3043 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
2874 render_process_host = GetDefaultSubframeProcessHost( 3044 render_process_host = GetDefaultSubframeProcessHost(
2875 browser_context, site_instance, is_for_guests_only); 3045 browser_context, site_instance, is_for_guests_only);
2876 break; 3046 break;
3047 case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
3048 render_process_host =
3049 FindReusableProcessHostForSite(browser_context, site_url);
3050 break;
2877 default: 3051 default:
2878 break; 3052 break;
2879 } 3053 }
2880 3054
2881 // If not (or if none found), see if we should reuse an existing process. 3055 // If not (or if none found), see if we should reuse an existing process.
2882 if (!render_process_host && 3056 if (!render_process_host &&
2883 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3057 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
2884 render_process_host = GetExistingProcessHost(browser_context, site_url); 3058 render_process_host = GetExistingProcessHost(browser_context, site_url);
2885 } 3059 }
2886 3060
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
3259 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); 3433 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
3260 if (!holder) { 3434 if (!holder) {
3261 holder = new DefaultSubframeProcessHostHolder(browser_context); 3435 holder = new DefaultSubframeProcessHostHolder(browser_context);
3262 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, 3436 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
3263 base::WrapUnique(holder)); 3437 base::WrapUnique(holder));
3264 } 3438 }
3265 3439
3266 return holder->GetProcessHost(site_instance, is_for_guests_only); 3440 return holder->GetProcessHost(site_instance, is_for_guests_only);
3267 } 3441 }
3268 3442
3443 // static
3444 RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
3445 BrowserContext* browser_context,
3446 const GURL& site_url) {
3447 if (site_url.is_empty())
3448 return nullptr;
3449
3450 std::set<RenderProcessHost*> eligible_foreground_hosts;
3451 std::set<RenderProcessHost*> eligible_background_hosts;
3452
3453 // First, add the RenderProcessHosts expecting a navigation to |site_url| to
3454 // the list of eligible RenderProcessHosts.
3455 SiteProcessCountTracker* pending_tracker =
3456 static_cast<SiteProcessCountTracker*>(
3457 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
3458 if (pending_tracker) {
3459 pending_tracker->FindRenderProcessesForSite(
3460 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3461 }
3462
3463 if (eligible_foreground_hosts.empty()) {
3464 // If needed, add the RenderProcessHosts hosting a frame for |site_url| to
3465 // the list of eligible RenderProcessHosts.
3466 SiteProcessCountTracker* committed_tracker =
3467 static_cast<SiteProcessCountTracker*>(
3468 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
3469 if (committed_tracker) {
3470 committed_tracker->FindRenderProcessesForSite(
3471 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3472 }
3473 }
3474
3475 if (!eligible_foreground_hosts.empty()) {
3476 int index = base::RandInt(0, eligible_foreground_hosts.size() - 1);
3477 auto iterator = eligible_foreground_hosts.begin();
3478 for (int i = 0; i < index; ++i)
3479 ++iterator;
3480 return (*iterator);
3481 }
3482
3483 if (!eligible_background_hosts.empty()) {
3484 int index = base::RandInt(0, eligible_background_hosts.size() - 1);
3485 auto iterator = eligible_background_hosts.begin();
3486 for (int i = 0; i < index; ++i)
3487 ++iterator;
3488 return (*iterator);
3489 }
3490
3491 return nullptr;
3492 }
3493
3269 #if BUILDFLAG(ENABLE_WEBRTC) 3494 #if BUILDFLAG(ENABLE_WEBRTC)
3270 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { 3495 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
3271 BrowserThread::PostTask( 3496 BrowserThread::PostTask(
3272 BrowserThread::UI, FROM_HERE, 3497 BrowserThread::UI, FROM_HERE,
3273 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, 3498 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
3274 weak_factory_.GetWeakPtr(), id)); 3499 weak_factory_.GetWeakPtr(), id));
3275 } 3500 }
3276 3501
3277 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { 3502 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
3278 BrowserThread::PostTask( 3503 BrowserThread::PostTask(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3349 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error; 3574 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3350 3575
3351 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3576 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3352 // Capture the error message in a crash key value. 3577 // Capture the error message in a crash key value.
3353 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3578 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3354 bad_message::ReceivedBadMessage(render_process_id, 3579 bad_message::ReceivedBadMessage(render_process_id,
3355 bad_message::RPH_MOJO_PROCESS_ERROR); 3580 bad_message::RPH_MOJO_PROCESS_ERROR);
3356 } 3581 }
3357 3582
3358 } // namespace content 3583 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698