1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TASK_SCHEDULER_SCHEDULER_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_ 6 #define BASE_TASK_SCHEDULER_SCHEDULER_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_ 7 8 #include <memory> 9 #include <string> 10 #include <vector> 11 12 #include "base/base_export.h" 13 #include "base/macros.h" 14 #include "base/memory/ref_counted.h" 15 #include "base/task_scheduler/environment_config.h" 16 #include "base/task_scheduler/scheduler_lock.h" 17 #include "base/task_scheduler/single_thread_task_runner_thread_mode.h" 18 #include "base/task_scheduler/tracked_ref.h" 19 #include "base/threading/platform_thread.h" 20 #include "build/build_config.h" 21 22 namespace base { 23 24 class TaskTraits; 25 class SchedulerWorkerObserver; 26 class SingleThreadTaskRunner; 27 28 namespace internal { 29 30 class DelayedTaskManager; 31 class SchedulerWorker; 32 class TaskTracker; 33 34 namespace { 35 36 class SchedulerWorkerDelegate; 37 38 } // namespace 39 40 // Manages a pool of threads which are each associated with one or more 41 // SingleThreadTaskRunners. 42 // 43 // SingleThreadTaskRunners using SingleThreadTaskRunnerThreadMode::SHARED are 44 // backed by shared SchedulerWorkers for each COM+task environment combination. 45 // These workers are lazily instantiated and then only reclaimed during 46 // JoinForTesting() 47 // 48 // No threads are created (and hence no tasks can run) before Start() is called. 49 // 50 // This class is thread-safe. 51 class BASE_EXPORT SchedulerSingleThreadTaskRunnerManager final { 52 public: 53 SchedulerSingleThreadTaskRunnerManager( 54 TrackedRef<TaskTracker> task_tracker, 55 DelayedTaskManager* delayed_task_manager); 56 ~SchedulerSingleThreadTaskRunnerManager(); 57 58 // Starts threads for existing SingleThreadTaskRunners and allows threads to 59 // be started when SingleThreadTaskRunners are created in the future. If 60 // specified, |scheduler_worker_observer| will be notified when a worker 61 // enters and exits its main function. It must not be destroyed before 62 // JoinForTesting() has returned (must never be destroyed in production). 63 void Start(SchedulerWorkerObserver* scheduler_worker_observer = nullptr); 64 65 // Creates a SingleThreadTaskRunner which runs tasks with |traits| on a thread 66 // named "TaskSchedulerSingleThread[Shared]" + 67 // kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix + 68 // index. 69 scoped_refptr<SingleThreadTaskRunner> CreateSingleThreadTaskRunnerWithTraits( 70 const TaskTraits& traits, 71 SingleThreadTaskRunnerThreadMode thread_mode); 72 73 #if defined(OS_WIN) 74 // Creates a SingleThreadTaskRunner which runs tasks with |traits| on a COM 75 // STA thread named "TaskSchedulerSingleThreadCOMSTA[Shared]" + 76 // kEnvironmentParams[GetEnvironmentIndexForTraits(traits)].name_suffix + 77 // index. 78 scoped_refptr<SingleThreadTaskRunner> CreateCOMSTATaskRunnerWithTraits( 79 const TaskTraits& traits, 80 SingleThreadTaskRunnerThreadMode thread_mode); 81 #endif // defined(OS_WIN) 82 83 void JoinForTesting(); 84 85 private: 86 class SchedulerSingleThreadTaskRunner; 87 88 enum ContinueOnShutdown { 89 IS_CONTINUE_ON_SHUTDOWN, 90 IS_NOT_CONTINUE_ON_SHUTDOWN, 91 CONTINUE_ON_SHUTDOWN_COUNT, 92 }; 93 94 static ContinueOnShutdown TraitsToContinueOnShutdown( 95 const TaskTraits& traits); 96 97 template <typename DelegateType> 98 scoped_refptr<SchedulerSingleThreadTaskRunner> CreateTaskRunnerWithTraitsImpl( 99 const TaskTraits& traits, 100 SingleThreadTaskRunnerThreadMode thread_mode); 101 102 template <typename DelegateType> 103 std::unique_ptr<SchedulerWorkerDelegate> CreateSchedulerWorkerDelegate( 104 const std::string& name, 105 int id, 106 SingleThreadTaskRunnerThreadMode thread_mode); 107 108 template <typename DelegateType> 109 SchedulerWorker* CreateAndRegisterSchedulerWorker( 110 const std::string& name, 111 SingleThreadTaskRunnerThreadMode thread_mode, 112 ThreadPriority priority_hint); 113 114 template <typename DelegateType> 115 SchedulerWorker*& GetSharedSchedulerWorkerForTraits(const TaskTraits& traits); 116 117 void UnregisterSchedulerWorker(SchedulerWorker* worker); 118 119 void ReleaseSharedSchedulerWorkers(); 120 121 const TrackedRef<TaskTracker> task_tracker_; 122 DelayedTaskManager* const delayed_task_manager_; 123 124 // Optional observer notified when a worker enters and exits its main 125 // function. Set in Start() and never modified afterwards. 126 SchedulerWorkerObserver* scheduler_worker_observer_ = nullptr; 127 128 // Synchronizes access to all members below. 129 SchedulerLock lock_; 130 std::vector<scoped_refptr<SchedulerWorker>> workers_; 131 int next_worker_id_ = 0; 132 133 // Workers for SingleThreadTaskRunnerThreadMode::SHARED tasks. It is 134 // important to have separate threads for CONTINUE_ON_SHUTDOWN and non- 135 // CONTINUE_ON_SHUTDOWN to avoid being in a situation where a 136 // CONTINUE_ON_SHUTDOWN task effectively blocks shutdown by preventing a 137 // BLOCK_SHUTDOWN task to be scheduled. https://crbug.com/829786 138 SchedulerWorker* shared_scheduler_workers_[ENVIRONMENT_COUNT] 139 [CONTINUE_ON_SHUTDOWN_COUNT] = {}; 140 #if defined(OS_WIN) 141 SchedulerWorker* shared_com_scheduler_workers_[ENVIRONMENT_COUNT] 142 [CONTINUE_ON_SHUTDOWN_COUNT] = 143 {}; 144 #endif // defined(OS_WIN) 145 146 // Set to true when Start() is called. 147 bool started_ = false; 148 149 DISALLOW_COPY_AND_ASSIGN(SchedulerSingleThreadTaskRunnerManager); 150 }; 151 152 } // namespace internal 153 } // namespace base 154 155 #endif // BASE_TASK_SCHEDULER_SCHEDULER_SINGLE_THREAD_TASK_RUNNER_MANAGER_H_ 156