Index: content/renderer/render_process_impl.cc |
diff --git a/content/renderer/render_process_impl.cc b/content/renderer/render_process_impl.cc |
index 0ad4d1b0066be8c76af12461a3d9c798bd51371a..1c7fa4510424a9b24f7e512db36cd1906cfd267b 100644 |
--- a/content/renderer/render_process_impl.cc |
+++ b/content/renderer/render_process_impl.cc |
@@ -12,10 +12,18 @@ |
#include <mlang.h> |
#endif |
+#include <stddef.h> |
+ |
+#include <vector> |
+ |
#include "base/command_line.h" |
#include "base/compiler_specific.h" |
#include "base/feature_list.h" |
#include "base/sys_info.h" |
+#include "base/task_scheduler/scheduler_worker_pool_params.h" |
+#include "base/task_scheduler/task_scheduler.h" |
+#include "base/task_scheduler/task_traits.h" |
+#include "base/threading/sequenced_worker_pool.h" |
#include "content/child/site_isolation_stats_gatherer.h" |
#include "content/public/common/content_features.h" |
#include "content/public/common/content_switches.h" |
@@ -50,6 +58,72 @@ void SetV8FlagIfHasSwitch(const char* switch_name, const char* v8_flag) { |
} |
} |
+bool IsSingleProcess() { |
+ return base::CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kSingleProcess); |
+} |
+ |
+enum WorkerPoolType : size_t { |
+ BACKGROUND_WORKER_POOL = 0, |
+ FOREGROUND_WORKER_POOL, |
+ WORKER_POOL_COUNT // Always last. |
+}; |
+ |
+size_t GetTaskSchedulerWorkerPoolIndexForTraits( |
+ const base::TaskTraits& traits) { |
+ return traits.priority() == base::TaskPriority::BACKGROUND |
gab
2016/11/15 20:25:05
DCHECK(!traits.with_file_io());
fdoray
2016/11/16 16:40:52
Done.
|
+ ? BACKGROUND_WORKER_POOL |
+ : FOREGROUND_WORKER_POOL; |
+} |
+ |
+void InitializeTaskScheduler() { |
+ if (IsSingleProcess()) { |
+ // If this renderer runs in the browser process, there should already be a |
+ // TaskScheduler and redirection settings shouldn't be changed. |
+ DCHECK(base::TaskScheduler::GetInstance()); |
+ return; |
+ } |
+ DCHECK(!base::TaskScheduler::GetInstance()); |
+ |
+ int max_background_threads = 0; |
+ base::TimeDelta background_reclaim_time; |
+ int max_foreground_threads = 0; |
+ base::TimeDelta foreground_reclaim_time; |
+ bool redirect_sequenced_worker_pool = false; |
+ |
+ content::GetContentClient() |
+ ->renderer() |
+ ->GetTaskSchedulerInitializationArguments( |
+ &max_background_threads, &background_reclaim_time, |
+ &max_foreground_threads, &foreground_reclaim_time, |
+ &redirect_sequenced_worker_pool); |
+ |
+ DCHECK_GT(max_background_threads, 0); |
robliao
2016/11/15 20:31:51
Hitting this DCHECK and the one below seems like i
robliao
2016/11/15 20:32:36
create tasks -> run tasks
gab
2016/11/15 20:42:47
No need to CHECK IMO, DCHECK documents runtime inv
robliao
2016/11/15 20:49:08
This would be pretty fatal to the process. We alre
gab
2016/11/15 22:04:30
But the CHECK in SchedulerWorkerPoolImpl::Initiali
fdoray
2016/11/16 16:40:52
These DCHECKs will only fail if GetTaskSchedulerIn
gab
2016/11/16 16:58:06
Agreed.
|
+ DCHECK(!background_reclaim_time.is_zero()); |
+ DCHECK_GT(max_foreground_threads, 0); |
+ DCHECK(!foreground_reclaim_time.is_zero()); |
+ |
+ std::vector<base::SchedulerWorkerPoolParams> worker_pool_params_vector; |
+ DCHECK_EQ(BACKGROUND_WORKER_POOL, worker_pool_params_vector.size()); |
+ worker_pool_params_vector.emplace_back( |
+ "RendererBackground", base::ThreadPriority::BACKGROUND, |
+ base::SchedulerWorkerPoolParams::IORestriction::DISALLOWED, |
+ max_background_threads, background_reclaim_time); |
+ DCHECK_EQ(FOREGROUND_WORKER_POOL, worker_pool_params_vector.size()); |
+ worker_pool_params_vector.emplace_back( |
+ "RendererForeground", base::ThreadPriority::NORMAL, |
+ base::SchedulerWorkerPoolParams::IORestriction::DISALLOWED, |
+ max_foreground_threads, foreground_reclaim_time); |
+ DCHECK_EQ(WORKER_POOL_COUNT, worker_pool_params_vector.size()); |
+ |
+ base::TaskScheduler::CreateAndSetDefaultTaskScheduler( |
+ worker_pool_params_vector, |
+ base::Bind(&GetTaskSchedulerWorkerPoolIndexForTraits)); |
+ |
+ if (redirect_sequenced_worker_pool) |
+ base::SequencedWorkerPool::RedirectToTaskSchedulerForProcess(); |
+} |
+ |
} // namespace |
namespace content { |
@@ -103,6 +177,8 @@ RenderProcessImpl::RenderProcessImpl() |
SiteIsolationStatsGatherer::SetEnabled( |
GetContentClient()->renderer()->ShouldGatherSiteIsolationStats()); |
+ |
+ InitializeTaskScheduler(); |
} |
RenderProcessImpl::~RenderProcessImpl() { |
@@ -112,6 +188,11 @@ RenderProcessImpl::~RenderProcessImpl() { |
DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES"; |
#endif |
+ if (!IsSingleProcess()) { |
+ DCHECK(base::TaskScheduler::GetInstance()); |
+ base::TaskScheduler::GetInstance()->Shutdown(); |
+ } |
+ |
GetShutDownEvent()->Signal(); |
} |