OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 #include "base/task_scheduler/scheduler_thread_pool_impl.h" | 5 #include "base/task_scheduler/scheduler_worker_pool_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <unordered_set> | 10 #include <unordered_set> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 14 #include "base/bind_helpers.h" |
15 #include "base/callback.h" | 15 #include "base/callback.h" |
(...skipping 12 matching lines...) Expand all Loading... |
28 #include "base/task_scheduler/test_utils.h" | 28 #include "base/task_scheduler/test_utils.h" |
29 #include "base/threading/platform_thread.h" | 29 #include "base/threading/platform_thread.h" |
30 #include "base/threading/simple_thread.h" | 30 #include "base/threading/simple_thread.h" |
31 #include "base/threading/thread_restrictions.h" | 31 #include "base/threading/thread_restrictions.h" |
32 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
33 | 33 |
34 namespace base { | 34 namespace base { |
35 namespace internal { | 35 namespace internal { |
36 namespace { | 36 namespace { |
37 | 37 |
38 const size_t kNumThreadsInThreadPool = 4; | 38 const size_t kNumWorkersInWorkerPool = 4; |
39 const size_t kNumThreadsPostingTasks = 4; | 39 const size_t kNumThreadsPostingTasks = 4; |
40 const size_t kNumTasksPostedPerThread = 150; | 40 const size_t kNumTasksPostedPerThread = 150; |
41 | 41 |
42 using IORestriction = SchedulerThreadPoolImpl::IORestriction; | 42 using IORestriction = SchedulerWorkerPoolImpl::IORestriction; |
43 | 43 |
44 class TestDelayedTaskManager : public DelayedTaskManager { | 44 class TestDelayedTaskManager : public DelayedTaskManager { |
45 public: | 45 public: |
46 TestDelayedTaskManager() : DelayedTaskManager(Bind(&DoNothing)) {} | 46 TestDelayedTaskManager() : DelayedTaskManager(Bind(&DoNothing)) {} |
47 | 47 |
48 void SetCurrentTime(TimeTicks now) { now_ = now; } | 48 void SetCurrentTime(TimeTicks now) { now_ = now; } |
49 | 49 |
50 // DelayedTaskManager: | 50 // DelayedTaskManager: |
51 TimeTicks Now() const override { return now_; } | 51 TimeTicks Now() const override { return now_; } |
52 | 52 |
53 private: | 53 private: |
54 TimeTicks now_ = TimeTicks::Now(); | 54 TimeTicks now_ = TimeTicks::Now(); |
55 | 55 |
56 DISALLOW_COPY_AND_ASSIGN(TestDelayedTaskManager); | 56 DISALLOW_COPY_AND_ASSIGN(TestDelayedTaskManager); |
57 }; | 57 }; |
58 | 58 |
59 class TaskSchedulerThreadPoolImplTest | 59 class TaskSchedulerWorkerPoolImplTest |
60 : public testing::TestWithParam<ExecutionMode> { | 60 : public testing::TestWithParam<ExecutionMode> { |
61 protected: | 61 protected: |
62 TaskSchedulerThreadPoolImplTest() = default; | 62 TaskSchedulerWorkerPoolImplTest() = default; |
63 | 63 |
64 void SetUp() override { | 64 void SetUp() override { |
65 thread_pool_ = SchedulerThreadPoolImpl::Create( | 65 worker_pool_ = SchedulerWorkerPoolImpl::Create( |
66 "TestThreadPoolWithFileIO", ThreadPriority::NORMAL, | 66 "TestWorkerPoolWithFileIO", ThreadPriority::NORMAL, |
67 kNumThreadsInThreadPool, IORestriction::ALLOWED, | 67 kNumWorkersInWorkerPool, IORestriction::ALLOWED, |
68 Bind(&TaskSchedulerThreadPoolImplTest::ReEnqueueSequenceCallback, | 68 Bind(&TaskSchedulerWorkerPoolImplTest::ReEnqueueSequenceCallback, |
69 Unretained(this)), | 69 Unretained(this)), |
70 &task_tracker_, &delayed_task_manager_); | 70 &task_tracker_, &delayed_task_manager_); |
71 ASSERT_TRUE(thread_pool_); | 71 ASSERT_TRUE(worker_pool_); |
72 } | 72 } |
73 | 73 |
74 void TearDown() override { | 74 void TearDown() override { |
75 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 75 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
76 thread_pool_->JoinForTesting(); | 76 worker_pool_->JoinForTesting(); |
77 } | 77 } |
78 | 78 |
79 std::unique_ptr<SchedulerThreadPoolImpl> thread_pool_; | 79 std::unique_ptr<SchedulerWorkerPoolImpl> worker_pool_; |
80 | 80 |
81 TaskTracker task_tracker_; | 81 TaskTracker task_tracker_; |
82 TestDelayedTaskManager delayed_task_manager_; | 82 TestDelayedTaskManager delayed_task_manager_; |
83 | 83 |
84 private: | 84 private: |
85 void ReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | 85 void ReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
86 // In production code, this callback would be implemented by the | 86 // In production code, this callback would be implemented by the |
87 // TaskScheduler which would first determine which PriorityQueue the | 87 // TaskScheduler which would first determine which PriorityQueue the |
88 // sequence must be re-enqueued. | 88 // sequence must be re-enqueued. |
89 const SequenceSortKey sort_key(sequence->GetSortKey()); | 89 const SequenceSortKey sort_key(sequence->GetSortKey()); |
90 thread_pool_->ReEnqueueSequence(std::move(sequence), sort_key); | 90 worker_pool_->ReEnqueueSequence(std::move(sequence), sort_key); |
91 } | 91 } |
92 | 92 |
93 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerThreadPoolImplTest); | 93 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplTest); |
94 }; | 94 }; |
95 | 95 |
96 using PostNestedTask = test::TestTaskFactory::PostNestedTask; | 96 using PostNestedTask = test::TestTaskFactory::PostNestedTask; |
97 | 97 |
98 class ThreadPostingTasks : public SimpleThread { | 98 class ThreadPostingTasks : public SimpleThread { |
99 public: | 99 public: |
100 enum class WaitBeforePostTask { | 100 enum class WaitBeforePostTask { |
101 NO_WAIT, | 101 NO_WAIT, |
102 WAIT_FOR_ALL_THREADS_IDLE, | 102 WAIT_FOR_ALL_THREADS_IDLE, |
103 }; | 103 }; |
104 | 104 |
105 // Constructs a thread that posts tasks to |thread_pool| through an | 105 // Constructs a thread that posts tasks to |worker_pool| through an |
106 // |execution_mode| task runner. If |wait_before_post_task| is | 106 // |execution_mode| task runner. If |wait_before_post_task| is |
107 // WAIT_FOR_ALL_THREADS_IDLE, the thread waits until all worker threads in | 107 // WAIT_FOR_ALL_THREADS_IDLE, the thread waits until all worker threads in |
108 // |thread_pool| are idle before posting a new task. If |post_nested_task| is | 108 // |worker_pool| are idle before posting a new task. If |post_nested_task| is |
109 // YES, each task posted by this thread posts another task when it runs. | 109 // YES, each task posted by this thread posts another task when it runs. |
110 ThreadPostingTasks(SchedulerThreadPoolImpl* thread_pool, | 110 ThreadPostingTasks(SchedulerWorkerPoolImpl* worker_pool, |
111 ExecutionMode execution_mode, | 111 ExecutionMode execution_mode, |
112 WaitBeforePostTask wait_before_post_task, | 112 WaitBeforePostTask wait_before_post_task, |
113 PostNestedTask post_nested_task) | 113 PostNestedTask post_nested_task) |
114 : SimpleThread("ThreadPostingTasks"), | 114 : SimpleThread("ThreadPostingTasks"), |
115 thread_pool_(thread_pool), | 115 worker_pool_(worker_pool), |
116 wait_before_post_task_(wait_before_post_task), | 116 wait_before_post_task_(wait_before_post_task), |
117 post_nested_task_(post_nested_task), | 117 post_nested_task_(post_nested_task), |
118 factory_(thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), | 118 factory_(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), |
119 execution_mode), | 119 execution_mode), |
120 execution_mode) { | 120 execution_mode) { |
121 DCHECK(thread_pool_); | 121 DCHECK(worker_pool_); |
122 } | 122 } |
123 | 123 |
124 const test::TestTaskFactory* factory() const { return &factory_; } | 124 const test::TestTaskFactory* factory() const { return &factory_; } |
125 | 125 |
126 private: | 126 private: |
127 void Run() override { | 127 void Run() override { |
128 EXPECT_FALSE(factory_.task_runner()->RunsTasksOnCurrentThread()); | 128 EXPECT_FALSE(factory_.task_runner()->RunsTasksOnCurrentThread()); |
129 | 129 |
130 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) { | 130 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) { |
131 if (wait_before_post_task_ == | 131 if (wait_before_post_task_ == |
132 WaitBeforePostTask::WAIT_FOR_ALL_THREADS_IDLE) { | 132 WaitBeforePostTask::WAIT_FOR_ALL_THREADS_IDLE) { |
133 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 133 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
134 } | 134 } |
135 EXPECT_TRUE(factory_.PostTask(post_nested_task_, Closure())); | 135 EXPECT_TRUE(factory_.PostTask(post_nested_task_, Closure())); |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 SchedulerThreadPoolImpl* const thread_pool_; | 139 SchedulerWorkerPoolImpl* const worker_pool_; |
140 const scoped_refptr<TaskRunner> task_runner_; | 140 const scoped_refptr<TaskRunner> task_runner_; |
141 const WaitBeforePostTask wait_before_post_task_; | 141 const WaitBeforePostTask wait_before_post_task_; |
142 const PostNestedTask post_nested_task_; | 142 const PostNestedTask post_nested_task_; |
143 test::TestTaskFactory factory_; | 143 test::TestTaskFactory factory_; |
144 | 144 |
145 DISALLOW_COPY_AND_ASSIGN(ThreadPostingTasks); | 145 DISALLOW_COPY_AND_ASSIGN(ThreadPostingTasks); |
146 }; | 146 }; |
147 | 147 |
148 using WaitBeforePostTask = ThreadPostingTasks::WaitBeforePostTask; | 148 using WaitBeforePostTask = ThreadPostingTasks::WaitBeforePostTask; |
149 | 149 |
150 void ShouldNotRunCallback() { | 150 void ShouldNotRunCallback() { |
151 ADD_FAILURE() << "Ran a task that shouldn't run."; | 151 ADD_FAILURE() << "Ran a task that shouldn't run."; |
152 } | 152 } |
153 | 153 |
154 } // namespace | 154 } // namespace |
155 | 155 |
156 TEST_P(TaskSchedulerThreadPoolImplTest, PostTasks) { | 156 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasks) { |
157 // Create threads to post tasks. | 157 // Create threads to post tasks. |
158 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 158 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
159 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 159 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
160 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 160 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
161 thread_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, | 161 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, |
162 PostNestedTask::NO))); | 162 PostNestedTask::NO))); |
163 threads_posting_tasks.back()->Start(); | 163 threads_posting_tasks.back()->Start(); |
164 } | 164 } |
165 | 165 |
166 // Wait for all tasks to run. | 166 // Wait for all tasks to run. |
167 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 167 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
168 thread_posting_tasks->Join(); | 168 thread_posting_tasks->Join(); |
169 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 169 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
170 } | 170 } |
171 | 171 |
172 // Wait until all worker threads are idle to be sure that no task accesses | 172 // Wait until all worker threads are idle to be sure that no task accesses |
173 // its TestTaskFactory after |thread_posting_tasks| is destroyed. | 173 // its TestTaskFactory after |thread_posting_tasks| is destroyed. |
174 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 174 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
175 } | 175 } |
176 | 176 |
177 TEST_P(TaskSchedulerThreadPoolImplTest, PostTasksWaitAllThreadsIdle) { | 177 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWaitAllThreadsIdle) { |
178 // Create threads to post tasks. To verify that worker threads can sleep and | 178 // Create threads to post tasks. To verify that worker threads can sleep and |
179 // be woken up when new tasks are posted, wait for all threads to become idle | 179 // be woken up when new tasks are posted, wait for all threads to become idle |
180 // before posting a new task. | 180 // before posting a new task. |
181 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 181 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
182 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 182 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
183 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 183 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
184 thread_pool_.get(), GetParam(), | 184 worker_pool_.get(), GetParam(), |
185 WaitBeforePostTask::WAIT_FOR_ALL_THREADS_IDLE, PostNestedTask::NO))); | 185 WaitBeforePostTask::WAIT_FOR_ALL_THREADS_IDLE, PostNestedTask::NO))); |
186 threads_posting_tasks.back()->Start(); | 186 threads_posting_tasks.back()->Start(); |
187 } | 187 } |
188 | 188 |
189 // Wait for all tasks to run. | 189 // Wait for all tasks to run. |
190 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 190 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
191 thread_posting_tasks->Join(); | 191 thread_posting_tasks->Join(); |
192 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 192 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
193 } | 193 } |
194 | 194 |
195 // Wait until all worker threads are idle to be sure that no task accesses | 195 // Wait until all worker threads are idle to be sure that no task accesses |
196 // its TestTaskFactory after |thread_posting_tasks| is destroyed. | 196 // its TestTaskFactory after |thread_posting_tasks| is destroyed. |
197 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 197 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
198 } | 198 } |
199 | 199 |
200 TEST_P(TaskSchedulerThreadPoolImplTest, NestedPostTasks) { | 200 TEST_P(TaskSchedulerWorkerPoolImplTest, NestedPostTasks) { |
201 // Create threads to post tasks. Each task posted by these threads will post | 201 // Create threads to post tasks. Each task posted by these threads will post |
202 // another task when it runs. | 202 // another task when it runs. |
203 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; | 203 std::vector<std::unique_ptr<ThreadPostingTasks>> threads_posting_tasks; |
204 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { | 204 for (size_t i = 0; i < kNumThreadsPostingTasks; ++i) { |
205 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( | 205 threads_posting_tasks.push_back(WrapUnique(new ThreadPostingTasks( |
206 thread_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, | 206 worker_pool_.get(), GetParam(), WaitBeforePostTask::NO_WAIT, |
207 PostNestedTask::YES))); | 207 PostNestedTask::YES))); |
208 threads_posting_tasks.back()->Start(); | 208 threads_posting_tasks.back()->Start(); |
209 } | 209 } |
210 | 210 |
211 // Wait for all tasks to run. | 211 // Wait for all tasks to run. |
212 for (const auto& thread_posting_tasks : threads_posting_tasks) { | 212 for (const auto& thread_posting_tasks : threads_posting_tasks) { |
213 thread_posting_tasks->Join(); | 213 thread_posting_tasks->Join(); |
214 thread_posting_tasks->factory()->WaitForAllTasksToRun(); | 214 thread_posting_tasks->factory()->WaitForAllTasksToRun(); |
215 } | 215 } |
216 | 216 |
217 // Wait until all worker threads are idle to be sure that no task accesses | 217 // Wait until all worker threads are idle to be sure that no task accesses |
218 // its TestTaskFactory after |thread_posting_tasks| is destroyed. | 218 // its TestTaskFactory after |thread_posting_tasks| is destroyed. |
219 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 219 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
220 } | 220 } |
221 | 221 |
222 TEST_P(TaskSchedulerThreadPoolImplTest, PostTasksWithOneAvailableThread) { | 222 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTasksWithOneAvailableThread) { |
223 // Post blocking tasks to keep all threads busy except one until |event| is | 223 // Post blocking tasks to keep all threads busy except one until |event| is |
224 // signaled. Use different factories so that tasks are added to different | 224 // signaled. Use different factories so that tasks are added to different |
225 // sequences and can run simultaneously when the execution mode is SEQUENCED. | 225 // sequences and can run simultaneously when the execution mode is SEQUENCED. |
226 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 226 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
227 WaitableEvent::InitialState::NOT_SIGNALED); | 227 WaitableEvent::InitialState::NOT_SIGNALED); |
228 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; | 228 std::vector<std::unique_ptr<test::TestTaskFactory>> blocked_task_factories; |
229 for (size_t i = 0; i < (kNumThreadsInThreadPool - 1); ++i) { | 229 for (size_t i = 0; i < (kNumWorkersInWorkerPool - 1); ++i) { |
230 blocked_task_factories.push_back(WrapUnique(new test::TestTaskFactory( | 230 blocked_task_factories.push_back(WrapUnique(new test::TestTaskFactory( |
231 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 231 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
232 GetParam()))); | 232 GetParam()))); |
233 EXPECT_TRUE(blocked_task_factories.back()->PostTask( | 233 EXPECT_TRUE(blocked_task_factories.back()->PostTask( |
234 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 234 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
235 blocked_task_factories.back()->WaitForAllTasksToRun(); | 235 blocked_task_factories.back()->WaitForAllTasksToRun(); |
236 } | 236 } |
237 | 237 |
238 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact | 238 // Post |kNumTasksPostedPerThread| tasks that should all run despite the fact |
239 // that only one thread in |thread_pool_| isn't busy. | 239 // that only one thread in |worker_pool_| isn't busy. |
240 test::TestTaskFactory short_task_factory( | 240 test::TestTaskFactory short_task_factory( |
241 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 241 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
242 GetParam()); | 242 GetParam()); |
243 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) | 243 for (size_t i = 0; i < kNumTasksPostedPerThread; ++i) |
244 EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, Closure())); | 244 EXPECT_TRUE(short_task_factory.PostTask(PostNestedTask::NO, Closure())); |
245 short_task_factory.WaitForAllTasksToRun(); | 245 short_task_factory.WaitForAllTasksToRun(); |
246 | 246 |
247 // Release tasks waiting on |event|. | 247 // Release tasks waiting on |event|. |
248 event.Signal(); | 248 event.Signal(); |
249 | 249 |
250 // Wait until all worker threads are idle to be sure that no task accesses | 250 // Wait until all worker threads are idle to be sure that no task accesses |
251 // its TestTaskFactory after it is destroyed. | 251 // its TestTaskFactory after it is destroyed. |
252 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 252 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
253 } | 253 } |
254 | 254 |
255 TEST_P(TaskSchedulerThreadPoolImplTest, Saturate) { | 255 TEST_P(TaskSchedulerWorkerPoolImplTest, Saturate) { |
256 // Verify that it is possible to have |kNumThreadsInThreadPool| | 256 // Verify that it is possible to have |kNumWorkersInWorkerPool| |
257 // tasks/sequences running simultaneously. Use different factories so that the | 257 // tasks/sequences running simultaneously. Use different factories so that the |
258 // blocking tasks are added to different sequences and can run simultaneously | 258 // blocking tasks are added to different sequences and can run simultaneously |
259 // when the execution mode is SEQUENCED. | 259 // when the execution mode is SEQUENCED. |
260 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 260 WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
261 WaitableEvent::InitialState::NOT_SIGNALED); | 261 WaitableEvent::InitialState::NOT_SIGNALED); |
262 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; | 262 std::vector<std::unique_ptr<test::TestTaskFactory>> factories; |
263 for (size_t i = 0; i < kNumThreadsInThreadPool; ++i) { | 263 for (size_t i = 0; i < kNumWorkersInWorkerPool; ++i) { |
264 factories.push_back(WrapUnique(new test::TestTaskFactory( | 264 factories.push_back(WrapUnique(new test::TestTaskFactory( |
265 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), | 265 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()), |
266 GetParam()))); | 266 GetParam()))); |
267 EXPECT_TRUE(factories.back()->PostTask( | 267 EXPECT_TRUE(factories.back()->PostTask( |
268 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); | 268 PostNestedTask::NO, Bind(&WaitableEvent::Wait, Unretained(&event)))); |
269 factories.back()->WaitForAllTasksToRun(); | 269 factories.back()->WaitForAllTasksToRun(); |
270 } | 270 } |
271 | 271 |
272 // Release tasks waiting on |event|. | 272 // Release tasks waiting on |event|. |
273 event.Signal(); | 273 event.Signal(); |
274 | 274 |
275 // Wait until all worker threads are idle to be sure that no task accesses | 275 // Wait until all worker threads are idle to be sure that no task accesses |
276 // its TestTaskFactory after it is destroyed. | 276 // its TestTaskFactory after it is destroyed. |
277 thread_pool_->WaitForAllWorkerThreadsIdleForTesting(); | 277 worker_pool_->WaitForAllWorkerWorkersIdleForTesting(); |
278 } | 278 } |
279 | 279 |
280 // Verify that a Task can't be posted after shutdown. | 280 // Verify that a Task can't be posted after shutdown. |
281 TEST_P(TaskSchedulerThreadPoolImplTest, PostTaskAfterShutdown) { | 281 TEST_P(TaskSchedulerWorkerPoolImplTest, PostTaskAfterShutdown) { |
282 auto task_runner = | 282 auto task_runner = |
283 thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()); | 283 worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()); |
284 task_tracker_.Shutdown(); | 284 task_tracker_.Shutdown(); |
285 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback))); | 285 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, Bind(&ShouldNotRunCallback))); |
286 } | 286 } |
287 | 287 |
288 // Verify that a Task posted with a delay is added to the DelayedTaskManager and | 288 // Verify that a Task posted with a delay is added to the DelayedTaskManager and |
289 // doesn't run before its delay expires. | 289 // doesn't run before its delay expires. |
290 TEST_P(TaskSchedulerThreadPoolImplTest, PostDelayedTask) { | 290 TEST_P(TaskSchedulerWorkerPoolImplTest, PostDelayedTask) { |
291 EXPECT_TRUE(delayed_task_manager_.GetDelayedRunTime().is_null()); | 291 EXPECT_TRUE(delayed_task_manager_.GetDelayedRunTime().is_null()); |
292 | 292 |
293 // Post a delayed task. | 293 // Post a delayed task. |
294 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 294 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
295 WaitableEvent::InitialState::NOT_SIGNALED); | 295 WaitableEvent::InitialState::NOT_SIGNALED); |
296 EXPECT_TRUE(thread_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()) | 296 EXPECT_TRUE(worker_pool_->CreateTaskRunnerWithTraits(TaskTraits(), GetParam()) |
297 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal, | 297 ->PostDelayedTask(FROM_HERE, Bind(&WaitableEvent::Signal, |
298 Unretained(&task_ran)), | 298 Unretained(&task_ran)), |
299 TimeDelta::FromSeconds(10))); | 299 TimeDelta::FromSeconds(10))); |
300 | 300 |
301 // The task should have been added to the DelayedTaskManager. | 301 // The task should have been added to the DelayedTaskManager. |
302 EXPECT_FALSE(delayed_task_manager_.GetDelayedRunTime().is_null()); | 302 EXPECT_FALSE(delayed_task_manager_.GetDelayedRunTime().is_null()); |
303 | 303 |
304 // The task shouldn't run. | 304 // The task shouldn't run. |
305 EXPECT_FALSE(task_ran.IsSignaled()); | 305 EXPECT_FALSE(task_ran.IsSignaled()); |
306 | 306 |
307 // Fast-forward time and post tasks that are ripe for execution. | 307 // Fast-forward time and post tasks that are ripe for execution. |
308 delayed_task_manager_.SetCurrentTime( | 308 delayed_task_manager_.SetCurrentTime( |
309 delayed_task_manager_.GetDelayedRunTime()); | 309 delayed_task_manager_.GetDelayedRunTime()); |
310 delayed_task_manager_.PostReadyTasks(); | 310 delayed_task_manager_.PostReadyTasks(); |
311 | 311 |
312 // The task should run. | 312 // The task should run. |
313 task_ran.Wait(); | 313 task_ran.Wait(); |
314 } | 314 } |
315 | 315 |
316 INSTANTIATE_TEST_CASE_P(Parallel, | 316 INSTANTIATE_TEST_CASE_P(Parallel, |
317 TaskSchedulerThreadPoolImplTest, | 317 TaskSchedulerWorkerPoolImplTest, |
318 ::testing::Values(ExecutionMode::PARALLEL)); | 318 ::testing::Values(ExecutionMode::PARALLEL)); |
319 INSTANTIATE_TEST_CASE_P(Sequenced, | 319 INSTANTIATE_TEST_CASE_P(Sequenced, |
320 TaskSchedulerThreadPoolImplTest, | 320 TaskSchedulerWorkerPoolImplTest, |
321 ::testing::Values(ExecutionMode::SEQUENCED)); | 321 ::testing::Values(ExecutionMode::SEQUENCED)); |
322 INSTANTIATE_TEST_CASE_P(SingleThreaded, | 322 INSTANTIATE_TEST_CASE_P(SingleThreaded, |
323 TaskSchedulerThreadPoolImplTest, | 323 TaskSchedulerWorkerPoolImplTest, |
324 ::testing::Values(ExecutionMode::SINGLE_THREADED)); | 324 ::testing::Values(ExecutionMode::SINGLE_THREADED)); |
325 | 325 |
326 namespace { | 326 namespace { |
327 | 327 |
328 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { | 328 void NotReachedReEnqueueSequenceCallback(scoped_refptr<Sequence> sequence) { |
329 ADD_FAILURE() | 329 ADD_FAILURE() |
330 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; | 330 << "Unexpected invocation of NotReachedReEnqueueSequenceCallback."; |
331 } | 331 } |
332 | 332 |
333 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED | 333 // Verifies that the current thread allows I/O if |io_restriction| is ALLOWED |
334 // and disallows it otherwise. Signals |event| before returning. | 334 // and disallows it otherwise. Signals |event| before returning. |
335 void ExpectIORestriction(IORestriction io_restriction, WaitableEvent* event) { | 335 void ExpectIORestriction(IORestriction io_restriction, WaitableEvent* event) { |
336 DCHECK(event); | 336 DCHECK(event); |
337 | 337 |
338 if (io_restriction == IORestriction::ALLOWED) { | 338 if (io_restriction == IORestriction::ALLOWED) { |
339 ThreadRestrictions::AssertIOAllowed(); | 339 ThreadRestrictions::AssertIOAllowed(); |
340 } else { | 340 } else { |
341 static_assert( | 341 static_assert( |
342 ENABLE_THREAD_RESTRICTIONS == DCHECK_IS_ON(), | 342 ENABLE_THREAD_RESTRICTIONS == DCHECK_IS_ON(), |
343 "ENABLE_THREAD_RESTRICTIONS and DCHECK_IS_ON() have diverged."); | 343 "ENABLE_THREAD_RESTRICTIONS and DCHECK_IS_ON() have diverged."); |
344 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }, ""); | 344 EXPECT_DCHECK_DEATH({ ThreadRestrictions::AssertIOAllowed(); }, ""); |
345 } | 345 } |
346 | 346 |
347 event->Signal(); | 347 event->Signal(); |
348 } | 348 } |
349 | 349 |
350 class TaskSchedulerThreadPoolImplIORestrictionTest | 350 class TaskSchedulerWorkerPoolImplIORestrictionTest |
351 : public testing::TestWithParam<IORestriction> { | 351 : public testing::TestWithParam<IORestriction> { |
352 public: | 352 public: |
353 TaskSchedulerThreadPoolImplIORestrictionTest() = default; | 353 TaskSchedulerWorkerPoolImplIORestrictionTest() = default; |
354 | 354 |
355 private: | 355 private: |
356 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerThreadPoolImplIORestrictionTest); | 356 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerWorkerPoolImplIORestrictionTest); |
357 }; | 357 }; |
358 | 358 |
359 } // namespace | 359 } // namespace |
360 | 360 |
361 TEST_P(TaskSchedulerThreadPoolImplIORestrictionTest, IORestriction) { | 361 TEST_P(TaskSchedulerWorkerPoolImplIORestrictionTest, IORestriction) { |
362 TaskTracker task_tracker; | 362 TaskTracker task_tracker; |
363 DelayedTaskManager delayed_task_manager(Bind(&DoNothing)); | 363 DelayedTaskManager delayed_task_manager(Bind(&DoNothing)); |
364 | 364 |
365 auto thread_pool = SchedulerThreadPoolImpl::Create( | 365 auto worker_pool = SchedulerWorkerPoolImpl::Create( |
366 "TestThreadPoolWithParam", ThreadPriority::NORMAL, 1U, GetParam(), | 366 "TestWorkerPoolWithParam", ThreadPriority::NORMAL, 1U, GetParam(), |
367 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, | 367 Bind(&NotReachedReEnqueueSequenceCallback), &task_tracker, |
368 &delayed_task_manager); | 368 &delayed_task_manager); |
369 ASSERT_TRUE(thread_pool); | 369 ASSERT_TRUE(worker_pool); |
370 | 370 |
371 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 371 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
372 WaitableEvent::InitialState::NOT_SIGNALED); | 372 WaitableEvent::InitialState::NOT_SIGNALED); |
373 thread_pool->CreateTaskRunnerWithTraits(TaskTraits(), ExecutionMode::PARALLEL) | 373 worker_pool->CreateTaskRunnerWithTraits(TaskTraits(), ExecutionMode::PARALLEL) |
374 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); | 374 ->PostTask(FROM_HERE, Bind(&ExpectIORestriction, GetParam(), &task_ran)); |
375 task_ran.Wait(); | 375 task_ran.Wait(); |
376 | 376 |
377 thread_pool->JoinForTesting(); | 377 worker_pool->JoinForTesting(); |
378 } | 378 } |
379 | 379 |
380 INSTANTIATE_TEST_CASE_P(IOAllowed, | 380 INSTANTIATE_TEST_CASE_P(IOAllowed, |
381 TaskSchedulerThreadPoolImplIORestrictionTest, | 381 TaskSchedulerWorkerPoolImplIORestrictionTest, |
382 ::testing::Values(IORestriction::ALLOWED)); | 382 ::testing::Values(IORestriction::ALLOWED)); |
383 INSTANTIATE_TEST_CASE_P(IODisallowed, | 383 INSTANTIATE_TEST_CASE_P(IODisallowed, |
384 TaskSchedulerThreadPoolImplIORestrictionTest, | 384 TaskSchedulerWorkerPoolImplIORestrictionTest, |
385 ::testing::Values(IORestriction::DISALLOWED)); | 385 ::testing::Values(IORestriction::DISALLOWED)); |
386 | 386 |
387 } // namespace internal | 387 } // namespace internal |
388 } // namespace base | 388 } // namespace base |
OLD | NEW |