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

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 + fixed tests 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 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 debug builds, observe the RenderProcessHost destruction, to check
661 // that it is 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 #ifndef NDEBUG
706 host->RemoveObserver(this);
707 DCHECK(!HasProcess(host));
708 #endif
709 }
710
711 #ifndef NDEBUG
712 // Used in debug builds to ensure that RenderProcessHost don't persist in the
713 // map after they've been destroyed.
714 bool HasProcess(RenderProcessHost* process) {
715 for (auto iter : map_) {
716 std::map<ProcessID, Count>& counts_per_process = iter.second;
717 for (auto iter_process : counts_per_process) {
718 if (iter_process.first == process->GetID())
719 return true;
720 }
721 }
722 return false;
723 }
724 #endif
725
726 using ProcessID = int;
727 using Count = int;
728 using CountPerProcessPerSiteMap = std::map<GURL, std::map<ProcessID, Count>>;
729 CountPerProcessPerSiteMap map_;
730 };
731
632 } // namespace 732 } // namespace
633 733
634 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; 734 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
635 735
636 base::MessageLoop* g_in_process_thread; 736 base::MessageLoop* g_in_process_thread;
637 737
638 // Stores the maximum number of renderer processes the content module can 738 // Stores the maximum number of renderer processes the content module can
639 // create. 739 // create.
640 static size_t g_max_renderer_count_override = 0; 740 static size_t g_max_renderer_count_override = 0;
641 741
(...skipping 1099 matching lines...) Expand 10 before | Expand all | Expand 10 after
1741 DCHECK_GT(audio_stream_count_, 0); 1841 DCHECK_GT(audio_stream_count_, 0);
1742 --audio_stream_count_; 1842 --audio_stream_count_;
1743 UpdateProcessPriority(); 1843 UpdateProcessPriority();
1744 } 1844 }
1745 1845
1746 void RenderProcessHostImpl::set_render_process_host_factory( 1846 void RenderProcessHostImpl::set_render_process_host_factory(
1747 const RenderProcessHostFactory* rph_factory) { 1847 const RenderProcessHostFactory* rph_factory) {
1748 g_render_process_host_factory_ = rph_factory; 1848 g_render_process_host_factory_ = rph_factory;
1749 } 1849 }
1750 1850
1851 // static
1852 void RenderProcessHostImpl::AddFrameWithSite(
1853 BrowserContext* browser_context,
1854 RenderProcessHost* render_process_host,
1855 const GURL& site_url) {
1856 if (site_url.is_empty())
1857 return;
1858
1859 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1860 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1861 if (!tracker) {
1862 tracker = new SiteProcessCountTracker();
1863 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1864 base::WrapUnique(tracker));
1865 }
1866 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1867 }
1868
1869 // static
1870 void RenderProcessHostImpl::RemoveFrameWithSite(
1871 BrowserContext* browser_context,
1872 RenderProcessHost* render_process_host,
1873 const GURL& site_url) {
1874 if (site_url.is_empty())
1875 return;
1876
1877 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1878 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
1879 if (!tracker) {
1880 tracker = new SiteProcessCountTracker();
1881 browser_context->SetUserData(kCommittedSiteProcessCountTrackerKey,
1882 base::WrapUnique(tracker));
1883 }
1884 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1885 }
1886
1887 // static
1888 void RenderProcessHostImpl::AddExpectedNavigationToSite(
1889 BrowserContext* browser_context,
1890 RenderProcessHost* render_process_host,
1891 const GURL& site_url) {
1892 if (site_url.is_empty())
1893 return;
1894
1895 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1896 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1897 if (!tracker) {
1898 tracker = new SiteProcessCountTracker();
1899 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1900 base::WrapUnique(tracker));
1901 }
1902 tracker->IncrementSiteProcessCount(site_url, render_process_host->GetID());
1903 }
1904
1905 // static
1906 void RenderProcessHostImpl::RemoveExpectedNavigationToSite(
1907 BrowserContext* browser_context,
1908 RenderProcessHost* render_process_host,
1909 const GURL& site_url) {
1910 if (site_url.is_empty())
1911 return;
1912
1913 SiteProcessCountTracker* tracker = static_cast<SiteProcessCountTracker*>(
1914 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
1915 if (!tracker) {
1916 tracker = new SiteProcessCountTracker();
1917 browser_context->SetUserData(kPendingSiteProcessCountTrackerKey,
1918 base::WrapUnique(tracker));
1919 }
1920 tracker->DecrementSiteProcessCount(site_url, render_process_host->GetID());
1921 }
1922
1751 bool RenderProcessHostImpl::IsForGuestsOnly() const { 1923 bool RenderProcessHostImpl::IsForGuestsOnly() const {
1752 return is_for_guests_only_; 1924 return is_for_guests_only_;
1753 } 1925 }
1754 1926
1755 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 1927 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
1756 return storage_partition_impl_; 1928 return storage_partition_impl_;
1757 } 1929 }
1758 1930
1759 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) { 1931 static void AppendCompositorCommandLineFlags(base::CommandLine* command_line) {
1760 command_line->AppendSwitchASCII( 1932 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. 3039 // First, attempt to reuse an existing RenderProcessHost if necessary.
2868 switch (process_reuse_policy) { 3040 switch (process_reuse_policy) {
2869 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE: 3041 case SiteInstanceImpl::ProcessReusePolicy::PROCESS_PER_SITE:
2870 render_process_host = GetProcessHostForSite(browser_context, site_url); 3042 render_process_host = GetProcessHostForSite(browser_context, site_url);
2871 break; 3043 break;
2872 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS: 3044 case SiteInstanceImpl::ProcessReusePolicy::USE_DEFAULT_SUBFRAME_PROCESS:
2873 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled()); 3045 DCHECK(SiteIsolationPolicy::IsTopDocumentIsolationEnabled());
2874 render_process_host = GetDefaultSubframeProcessHost( 3046 render_process_host = GetDefaultSubframeProcessHost(
2875 browser_context, site_instance, is_for_guests_only); 3047 browser_context, site_instance, is_for_guests_only);
2876 break; 3048 break;
3049 case SiteInstanceImpl::ProcessReusePolicy::REUSE_PENDING_OR_COMMITTED_SITE:
3050 render_process_host =
3051 FindReusableProcessHostForSite(browser_context, site_url);
3052 break;
2877 default: 3053 default:
2878 break; 3054 break;
2879 } 3055 }
2880 3056
2881 // If not (or if none found), see if we should reuse an existing process. 3057 // If not (or if none found), see if we should reuse an existing process.
2882 if (!render_process_host && 3058 if (!render_process_host &&
2883 ShouldTryToUseExistingProcessHost(browser_context, site_url)) { 3059 ShouldTryToUseExistingProcessHost(browser_context, site_url)) {
2884 render_process_host = GetExistingProcessHost(browser_context, site_url); 3060 render_process_host = GetExistingProcessHost(browser_context, site_url);
2885 } 3061 }
2886 3062
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
3259 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey)); 3435 browser_context->GetUserData(&kDefaultSubframeProcessHostHolderKey));
3260 if (!holder) { 3436 if (!holder) {
3261 holder = new DefaultSubframeProcessHostHolder(browser_context); 3437 holder = new DefaultSubframeProcessHostHolder(browser_context);
3262 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey, 3438 browser_context->SetUserData(kDefaultSubframeProcessHostHolderKey,
3263 base::WrapUnique(holder)); 3439 base::WrapUnique(holder));
3264 } 3440 }
3265 3441
3266 return holder->GetProcessHost(site_instance, is_for_guests_only); 3442 return holder->GetProcessHost(site_instance, is_for_guests_only);
3267 } 3443 }
3268 3444
3445 // static
3446 RenderProcessHost* RenderProcessHostImpl::FindReusableProcessHostForSite(
3447 BrowserContext* browser_context,
3448 const GURL& site_url) {
3449 if (site_url.is_empty())
3450 return nullptr;
3451
3452 std::set<RenderProcessHost*> eligible_foreground_hosts;
3453 std::set<RenderProcessHost*> eligible_background_hosts;
3454
3455 // First, add the RenderProcessHosts expecting a navigation to |site_url| to
3456 // the list of eligible RenderProcessHosts.
3457 SiteProcessCountTracker* pending_tracker =
3458 static_cast<SiteProcessCountTracker*>(
3459 browser_context->GetUserData(kPendingSiteProcessCountTrackerKey));
3460 if (pending_tracker) {
3461 pending_tracker->FindRenderProcessesForSite(
3462 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3463 }
3464
3465 if (eligible_foreground_hosts.empty()) {
3466 // If needed, add the RenderProcessHosts hosting a frame for |site_url| to
3467 // the list of eligible RenderProcessHosts.
3468 SiteProcessCountTracker* committed_tracker =
3469 static_cast<SiteProcessCountTracker*>(
3470 browser_context->GetUserData(kCommittedSiteProcessCountTrackerKey));
3471 if (committed_tracker) {
3472 committed_tracker->FindRenderProcessesForSite(
3473 site_url, &eligible_foreground_hosts, &eligible_background_hosts);
3474 }
3475 }
3476
3477 if (!eligible_foreground_hosts.empty()) {
3478 int index = base::RandInt(0, eligible_foreground_hosts.size() - 1);
3479 auto iterator = eligible_foreground_hosts.begin();
3480 for (int i = 0; i < index; ++i)
3481 ++iterator;
3482 return (*iterator);
3483 }
3484
3485 if (!eligible_background_hosts.empty()) {
3486 int index = base::RandInt(0, eligible_background_hosts.size() - 1);
3487 auto iterator = eligible_background_hosts.begin();
3488 for (int i = 0; i < index; ++i)
3489 ++iterator;
3490 return (*iterator);
3491 }
3492
3493 return nullptr;
3494 }
3495
3269 #if BUILDFLAG(ENABLE_WEBRTC) 3496 #if BUILDFLAG(ENABLE_WEBRTC)
3270 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) { 3497 void RenderProcessHostImpl::OnRegisterAecDumpConsumer(int id) {
3271 BrowserThread::PostTask( 3498 BrowserThread::PostTask(
3272 BrowserThread::UI, FROM_HERE, 3499 BrowserThread::UI, FROM_HERE,
3273 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread, 3500 base::Bind(&RenderProcessHostImpl::RegisterAecDumpConsumerOnUIThread,
3274 weak_factory_.GetWeakPtr(), id)); 3501 weak_factory_.GetWeakPtr(), id));
3275 } 3502 }
3276 3503
3277 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) { 3504 void RenderProcessHostImpl::OnUnregisterAecDumpConsumer(int id) {
3278 BrowserThread::PostTask( 3505 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; 3576 LOG(ERROR) << "Terminating render process for bad Mojo message: " << error;
3350 3577
3351 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing. 3578 // The ReceivedBadMessage call below will trigger a DumpWithoutCrashing.
3352 // Capture the error message in a crash key value. 3579 // Capture the error message in a crash key value.
3353 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error); 3580 base::debug::ScopedCrashKey error_key_value("mojo-message-error", error);
3354 bad_message::ReceivedBadMessage(render_process_id, 3581 bad_message::ReceivedBadMessage(render_process_id,
3355 bad_message::RPH_MOJO_PROCESS_ERROR); 3582 bad_message::RPH_MOJO_PROCESS_ERROR);
3356 } 3583 }
3357 3584
3358 } // namespace content 3585 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698