OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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_single_thread_task_runner_manager.h" | 5 #include "base/task_scheduler/scheduler_single_thread_task_runner_manager.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/synchronization/atomic_flag.h" | 9 #include "base/synchronization/atomic_flag.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
11 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
12 #include "base/task_scheduler/delayed_task_manager.h" | 12 #include "base/task_scheduler/delayed_task_manager.h" |
13 #include "base/task_scheduler/post_task.h" | 13 #include "base/task_scheduler/post_task.h" |
14 #include "base/task_scheduler/scheduler_worker_pool_params.h" | 14 #include "base/task_scheduler/scheduler_worker_pool_params.h" |
15 #include "base/task_scheduler/task_tracker.h" | 15 #include "base/task_scheduler/task_tracker.h" |
16 #include "base/task_scheduler/task_traits.h" | 16 #include "base/task_scheduler/task_traits.h" |
17 #include "base/test/gtest_util.h" | |
17 #include "base/test/test_timeouts.h" | 18 #include "base/test/test_timeouts.h" |
18 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
19 #include "base/threading/simple_thread.h" | 20 #include "base/threading/simple_thread.h" |
20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 22 #include "testing/gtest/include/gtest/gtest.h" |
22 | 23 |
23 #if defined(OS_WIN) | 24 #if defined(OS_WIN) |
24 #include <windows.h> | 25 #include <windows.h> |
25 #include <objbase.h> | 26 #include <objbase.h> |
26 | 27 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
75 void CaptureThreadRef(PlatformThreadRef* thread_ref) { | 76 void CaptureThreadRef(PlatformThreadRef* thread_ref) { |
76 ASSERT_TRUE(thread_ref); | 77 ASSERT_TRUE(thread_ref); |
77 *thread_ref = PlatformThread::CurrentRef(); | 78 *thread_ref = PlatformThread::CurrentRef(); |
78 } | 79 } |
79 | 80 |
80 void CaptureThreadPriority(ThreadPriority* thread_priority) { | 81 void CaptureThreadPriority(ThreadPriority* thread_priority) { |
81 ASSERT_TRUE(thread_priority); | 82 ASSERT_TRUE(thread_priority); |
82 *thread_priority = PlatformThread::GetCurrentThreadPriority(); | 83 *thread_priority = PlatformThread::GetCurrentThreadPriority(); |
83 } | 84 } |
84 | 85 |
86 void CaptureThreadName(std::string* thread_name) { | |
87 *thread_name = PlatformThread::GetName(); | |
88 } | |
89 | |
85 void ShouldNotRun() { | 90 void ShouldNotRun() { |
86 ADD_FAILURE() << "Ran a task that shouldn't run."; | 91 ADD_FAILURE() << "Ran a task that shouldn't run."; |
87 } | 92 } |
88 | 93 |
89 } // namespace | 94 } // namespace |
90 | 95 |
91 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 96 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
92 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 97 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
93 single_thread_task_runner_manager_ | 98 single_thread_task_runner_manager_ |
94 ->CreateSingleThreadTaskRunnerWithTraits( | 99 ->CreateSingleThreadTaskRunnerWithTraits( |
95 "A", ThreadPriority::NORMAL, | 100 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, |
96 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | 101 SingleThreadTaskRunnerThreadMode::DEDICATED); |
97 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 102 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
98 single_thread_task_runner_manager_ | 103 single_thread_task_runner_manager_ |
99 ->CreateSingleThreadTaskRunnerWithTraits( | 104 ->CreateSingleThreadTaskRunnerWithTraits( |
100 "B", ThreadPriority::NORMAL, | 105 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, |
101 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | 106 SingleThreadTaskRunnerThreadMode::DEDICATED); |
102 | 107 |
103 PlatformThreadRef thread_ref_1; | 108 PlatformThreadRef thread_ref_1; |
104 task_runner_1->PostTask(FROM_HERE, | 109 task_runner_1->PostTask(FROM_HERE, |
105 BindOnce(&CaptureThreadRef, &thread_ref_1)); | 110 BindOnce(&CaptureThreadRef, &thread_ref_1)); |
106 PlatformThreadRef thread_ref_2; | 111 PlatformThreadRef thread_ref_2; |
107 task_runner_2->PostTask(FROM_HERE, | 112 task_runner_2->PostTask(FROM_HERE, |
108 BindOnce(&CaptureThreadRef, &thread_ref_2)); | 113 BindOnce(&CaptureThreadRef, &thread_ref_2)); |
109 | 114 |
110 task_tracker_.Shutdown(); | 115 task_tracker_.Shutdown(); |
111 | 116 |
112 ASSERT_FALSE(thread_ref_1.is_null()); | 117 ASSERT_FALSE(thread_ref_1.is_null()); |
113 ASSERT_FALSE(thread_ref_2.is_null()); | 118 ASSERT_FALSE(thread_ref_2.is_null()); |
114 EXPECT_NE(thread_ref_1, thread_ref_2); | 119 EXPECT_NE(thread_ref_1, thread_ref_2); |
115 } | 120 } |
116 | 121 |
117 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 122 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, SameThreadUsed) { |
123 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | |
124 single_thread_task_runner_manager_ | |
125 ->CreateSingleThreadTaskRunnerWithTraits( | |
126 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
127 SingleThreadTaskRunnerThreadMode::SHARED); | |
128 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | |
129 single_thread_task_runner_manager_ | |
130 ->CreateSingleThreadTaskRunnerWithTraits( | |
131 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
132 SingleThreadTaskRunnerThreadMode::SHARED); | |
133 | |
134 PlatformThreadRef thread_ref_1; | |
135 task_runner_1->PostTask(FROM_HERE, | |
136 BindOnce(&CaptureThreadRef, &thread_ref_1)); | |
137 PlatformThreadRef thread_ref_2; | |
138 task_runner_2->PostTask(FROM_HERE, | |
139 BindOnce(&CaptureThreadRef, &thread_ref_2)); | |
140 | |
141 task_tracker_.Shutdown(); | |
142 | |
143 ASSERT_FALSE(thread_ref_1.is_null()); | |
144 ASSERT_FALSE(thread_ref_2.is_null()); | |
145 EXPECT_EQ(thread_ref_1, thread_ref_2); | |
146 } | |
147 | |
148 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | |
149 RunsTasksOnCurrentThread) { | |
gab
2017/05/25 18:47:00
This test should work in both modes, parametrize a
robliao
2017/05/30 20:01:07
Since we do check the thread handle for the COM ca
| |
150 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | |
151 single_thread_task_runner_manager_ | |
152 ->CreateSingleThreadTaskRunnerWithTraits( | |
153 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
154 SingleThreadTaskRunnerThreadMode::DEDICATED); | |
155 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | |
156 single_thread_task_runner_manager_ | |
157 ->CreateSingleThreadTaskRunnerWithTraits( | |
158 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
159 SingleThreadTaskRunnerThreadMode::DEDICATED); | |
160 | |
161 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | |
162 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | |
163 | |
164 task_runner_1->PostTask( | |
165 FROM_HERE, BindOnce( | |
166 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | |
167 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | |
168 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); | |
169 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | |
170 }, | |
171 task_runner_1, task_runner_2)); | |
172 | |
173 task_runner_2->PostTask( | |
174 FROM_HERE, BindOnce( | |
175 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | |
176 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | |
177 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | |
178 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread()); | |
179 }, | |
180 task_runner_1, task_runner_2)); | |
181 | |
182 task_tracker_.Shutdown(); | |
183 } | |
184 | |
185 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | |
186 SharedWithBaseSyncPrimitivesDCHECKs) { | |
187 EXPECT_DCHECK_DEATH({ | |
188 single_thread_task_runner_manager_->CreateSingleThreadTaskRunnerWithTraits( | |
189 "A", {WithBaseSyncPrimitives()}, | |
190 SingleThreadTaskRunnerThreadMode::SHARED); | |
191 }); | |
192 } | |
193 | |
194 namespace { | |
195 | |
196 class TaskSchedulerSingleThreadTaskRunnerManagerCommonTest | |
197 : public TaskSchedulerSingleThreadTaskRunnerManagerTest, | |
198 public ::testing::WithParamInterface<SingleThreadTaskRunnerThreadMode> { | |
199 public: | |
200 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest() = default; | |
201 | |
202 private: | |
203 DISALLOW_COPY_AND_ASSIGN( | |
204 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest); | |
205 }; | |
206 | |
207 } // namespace | |
208 | |
209 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, | |
210 PrioritySetCorrectly) { | |
118 // Why are events used here instead of the task tracker? | 211 // Why are events used here instead of the task tracker? |
119 // Shutting down can cause priorities to get raised. This means we have to use | 212 // Shutting down can cause priorities to get raised. This means we have to use |
120 // events to determine when a task is run. | 213 // events to determine when a task is run. |
121 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 214 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
122 single_thread_task_runner_manager_ | 215 single_thread_task_runner_manager_ |
123 ->CreateSingleThreadTaskRunnerWithTraits("Background", | 216 ->CreateSingleThreadTaskRunnerWithTraits( |
124 ThreadPriority::BACKGROUND, | 217 "Background", {TaskPriority::BACKGROUND}, GetParam()); |
125 {TaskPriority::BACKGROUND}); | |
126 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = | 218 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = |
127 single_thread_task_runner_manager_ | 219 single_thread_task_runner_manager_ |
128 ->CreateSingleThreadTaskRunnerWithTraits( | 220 ->CreateSingleThreadTaskRunnerWithTraits( |
129 "Normal", ThreadPriority::NORMAL, {TaskPriority::USER_VISIBLE}); | 221 "Normal", {TaskPriority::USER_VISIBLE}, GetParam()); |
130 | 222 |
131 ThreadPriority thread_priority_background; | 223 ThreadPriority thread_priority_background; |
132 task_runner_background->PostTask( | 224 task_runner_background->PostTask( |
133 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 225 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); |
134 WaitableEvent waitable_event_background( | 226 WaitableEvent waitable_event_background( |
135 WaitableEvent::ResetPolicy::MANUAL, | 227 WaitableEvent::ResetPolicy::MANUAL, |
136 WaitableEvent::InitialState::NOT_SIGNALED); | 228 WaitableEvent::InitialState::NOT_SIGNALED); |
137 task_runner_background->PostTask( | 229 task_runner_background->PostTask( |
138 FROM_HERE, | 230 FROM_HERE, |
139 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 231 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
(...skipping 11 matching lines...) Expand all Loading... | |
151 waitable_event_background.Wait(); | 243 waitable_event_background.Wait(); |
152 waitable_event_normal.Wait(); | 244 waitable_event_normal.Wait(); |
153 | 245 |
154 if (Lock::HandlesMultipleThreadPriorities()) | 246 if (Lock::HandlesMultipleThreadPriorities()) |
155 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 247 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
156 else | 248 else |
157 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 249 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
158 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); | 250 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); |
159 } | 251 } |
160 | 252 |
161 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 253 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, ThreadNamesSet) { |
254 constexpr TaskTraits foo_traits = {TaskPriority::BACKGROUND, | |
255 TaskShutdownBehavior::BLOCK_SHUTDOWN}; | |
256 scoped_refptr<SingleThreadTaskRunner> foo_task_runner = | |
257 single_thread_task_runner_manager_ | |
258 ->CreateSingleThreadTaskRunnerWithTraits("MyName", foo_traits, | |
259 GetParam()); | |
260 std::string foo_captured_name; | |
261 foo_task_runner->PostTask(FROM_HERE, | |
262 BindOnce(&CaptureThreadName, &foo_captured_name)); | |
263 | |
264 constexpr TaskTraits user_blocking_traits = { | |
265 TaskPriority::USER_BLOCKING, MayBlock(), | |
266 TaskShutdownBehavior::BLOCK_SHUTDOWN}; | |
267 scoped_refptr<SingleThreadTaskRunner> user_blocking_task_runner = | |
268 single_thread_task_runner_manager_ | |
269 ->CreateSingleThreadTaskRunnerWithTraits("A", user_blocking_traits, | |
270 GetParam()); | |
271 | |
272 std::string user_blocking_captured_name; | |
273 user_blocking_task_runner->PostTask( | |
274 FROM_HERE, BindOnce(&CaptureThreadName, &user_blocking_captured_name)); | |
275 | |
276 task_tracker_.Shutdown(); | |
277 | |
278 EXPECT_NE(std::string::npos, foo_captured_name.find("MyName")); | |
279 EXPECT_NE(std::string::npos, | |
280 foo_captured_name.find( | |
281 kEnvironmentParams[GetEnvironmentIndexForTraits(foo_traits)] | |
282 .name_suffix)); | |
283 EXPECT_NE( | |
284 std::string::npos, | |
285 user_blocking_captured_name.find( | |
286 kEnvironmentParams[GetEnvironmentIndexForTraits(user_blocking_traits)] | |
287 .name_suffix)); | |
288 | |
289 if (GetParam() == SingleThreadTaskRunnerThreadMode::DEDICATED) { | |
290 EXPECT_EQ(std::string::npos, foo_captured_name.find("Shared")); | |
291 EXPECT_EQ(std::string::npos, user_blocking_captured_name.find("Shared")); | |
292 } else { | |
293 EXPECT_NE(std::string::npos, foo_captured_name.find("Shared")); | |
294 EXPECT_NE(std::string::npos, user_blocking_captured_name.find("Shared")); | |
295 } | |
296 } | |
297 | |
298 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, | |
299 PostTaskAfterShutdown) { | |
162 auto task_runner = single_thread_task_runner_manager_ | 300 auto task_runner = single_thread_task_runner_manager_ |
163 ->CreateSingleThreadTaskRunnerWithTraits( | 301 ->CreateSingleThreadTaskRunnerWithTraits( |
164 "A", ThreadPriority::NORMAL, TaskTraits()); | 302 "A", TaskTraits(), GetParam()); |
165 task_tracker_.Shutdown(); | 303 task_tracker_.Shutdown(); |
166 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); | 304 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); |
167 } | 305 } |
168 | 306 |
169 // Verify that a Task runs shortly after its delay expires. | 307 // Verify that a Task runs shortly after its delay expires. |
170 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 308 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, PostDelayedTask) { |
171 TimeTicks start_time = TimeTicks::Now(); | 309 TimeTicks start_time = TimeTicks::Now(); |
172 | 310 |
173 // Post a task with a short delay. | 311 // Post a task with a short delay. |
174 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 312 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
175 WaitableEvent::InitialState::NOT_SIGNALED); | 313 WaitableEvent::InitialState::NOT_SIGNALED); |
176 auto task_runner = single_thread_task_runner_manager_ | 314 auto task_runner = single_thread_task_runner_manager_ |
177 ->CreateSingleThreadTaskRunnerWithTraits( | 315 ->CreateSingleThreadTaskRunnerWithTraits( |
178 "A", ThreadPriority::NORMAL, TaskTraits()); | 316 "A", TaskTraits(), GetParam()); |
179 EXPECT_TRUE(task_runner->PostDelayedTask( | 317 EXPECT_TRUE(task_runner->PostDelayedTask( |
180 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), | 318 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), |
181 TestTimeouts::tiny_timeout())); | 319 TestTimeouts::tiny_timeout())); |
182 | 320 |
183 // Wait until the task runs. | 321 // Wait until the task runs. |
184 task_ran.Wait(); | 322 task_ran.Wait(); |
185 | 323 |
186 // Expect the task to run after its delay expires, but not more than 250 ms | 324 // Expect the task to run after its delay expires, but not more than 250 ms |
187 // after that. | 325 // after that. |
188 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 326 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
189 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 327 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
190 EXPECT_LT(actual_delay, | 328 EXPECT_LT(actual_delay, |
191 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 329 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
192 } | 330 } |
193 | 331 |
194 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 332 INSTANTIATE_TEST_CASE_P( |
195 RunsTasksOnCurrentThread) { | 333 AllModes, |
gab
2017/05/25 18:47:01
Should stay here as a Common test, no?
robliao
2017/05/30 20:01:07
See above.
| |
196 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 334 TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, |
197 single_thread_task_runner_manager_ | 335 ::testing::Values(SingleThreadTaskRunnerThreadMode::SHARED, |
198 ->CreateSingleThreadTaskRunnerWithTraits( | 336 SingleThreadTaskRunnerThreadMode::DEDICATED)); |
199 "A", ThreadPriority::NORMAL, | |
200 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | |
201 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | |
202 single_thread_task_runner_manager_ | |
203 ->CreateSingleThreadTaskRunnerWithTraits( | |
204 "B", ThreadPriority::NORMAL, | |
205 {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | |
206 | |
207 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | |
208 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | |
209 | |
210 task_runner_1->PostTask( | |
211 FROM_HERE, BindOnce( | |
212 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | |
213 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | |
214 EXPECT_TRUE(task_runner_1->RunsTasksOnCurrentThread()); | |
215 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | |
216 }, | |
217 task_runner_1, task_runner_2)); | |
218 | |
219 task_runner_2->PostTask( | |
220 FROM_HERE, BindOnce( | |
221 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | |
222 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | |
223 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | |
224 EXPECT_TRUE(task_runner_2->RunsTasksOnCurrentThread()); | |
225 }, | |
226 task_runner_1, task_runner_2)); | |
227 | |
228 task_tracker_.Shutdown(); | |
229 } | |
230 | 337 |
231 namespace { | 338 namespace { |
232 | 339 |
233 class CallJoinFromDifferentThread : public SimpleThread { | 340 class CallJoinFromDifferentThread : public SimpleThread { |
234 public: | 341 public: |
235 CallJoinFromDifferentThread( | 342 CallJoinFromDifferentThread( |
236 SchedulerSingleThreadTaskRunnerManager* manager_to_join) | 343 SchedulerSingleThreadTaskRunnerManager* manager_to_join) |
237 : SimpleThread("SchedulerSingleThreadTaskRunnerManagerJoinThread"), | 344 : SimpleThread("SchedulerSingleThreadTaskRunnerManagerJoinThread"), |
238 manager_to_join_(manager_to_join), | 345 manager_to_join_(manager_to_join), |
239 run_started_event_(WaitableEvent::ResetPolicy::MANUAL, | 346 run_started_event_(WaitableEvent::ResetPolicy::MANUAL, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 | 382 |
276 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { | 383 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, ConcurrentJoin) { |
277 // Exercises the codepath where the workers are unavailable for unregistration | 384 // Exercises the codepath where the workers are unavailable for unregistration |
278 // because of a Join call. | 385 // because of a Join call. |
279 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 386 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
280 WaitableEvent::InitialState::NOT_SIGNALED); | 387 WaitableEvent::InitialState::NOT_SIGNALED); |
281 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 388 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
282 WaitableEvent::InitialState::NOT_SIGNALED); | 389 WaitableEvent::InitialState::NOT_SIGNALED); |
283 | 390 |
284 { | 391 { |
285 auto task_runner = | 392 auto task_runner = single_thread_task_runner_manager_ |
286 single_thread_task_runner_manager_ | 393 ->CreateSingleThreadTaskRunnerWithTraits( |
287 ->CreateSingleThreadTaskRunnerWithTraits( | 394 "A", {WithBaseSyncPrimitives()}, |
288 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); | 395 SingleThreadTaskRunnerThreadMode::DEDICATED); |
289 EXPECT_TRUE(task_runner->PostTask( | 396 EXPECT_TRUE(task_runner->PostTask( |
290 FROM_HERE, | 397 FROM_HERE, |
291 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 398 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
292 EXPECT_TRUE(task_runner->PostTask( | 399 EXPECT_TRUE(task_runner->PostTask( |
293 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 400 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
294 } | 401 } |
295 | 402 |
296 task_running.Wait(); | 403 task_running.Wait(); |
297 CallJoinFromDifferentThread join_from_different_thread( | 404 CallJoinFromDifferentThread join_from_different_thread( |
298 single_thread_task_runner_manager_.get()); | 405 single_thread_task_runner_manager_.get()); |
299 join_from_different_thread.Start(); | 406 join_from_different_thread.Start(); |
300 join_from_different_thread.WaitForRunToStart(); | 407 join_from_different_thread.WaitForRunToStart(); |
301 task_blocking.Signal(); | 408 task_blocking.Signal(); |
302 join_from_different_thread.Join(); | 409 join_from_different_thread.Join(); |
303 } | 410 } |
304 | 411 |
305 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 412 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
306 ConcurrentJoinExtraSkippedTask) { | 413 ConcurrentJoinExtraSkippedTask) { |
307 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 414 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
308 // SingleThreadTaskRunners to unregister themselves. | 415 // SingleThreadTaskRunners to unregister themselves. |
309 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 416 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
310 WaitableEvent::InitialState::NOT_SIGNALED); | 417 WaitableEvent::InitialState::NOT_SIGNALED); |
311 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 418 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
312 WaitableEvent::InitialState::NOT_SIGNALED); | 419 WaitableEvent::InitialState::NOT_SIGNALED); |
313 | 420 |
314 { | 421 { |
315 auto task_runner = | 422 auto task_runner = single_thread_task_runner_manager_ |
316 single_thread_task_runner_manager_ | 423 ->CreateSingleThreadTaskRunnerWithTraits( |
317 ->CreateSingleThreadTaskRunnerWithTraits( | 424 "A", {WithBaseSyncPrimitives()}, |
318 "A", ThreadPriority::NORMAL, {WithBaseSyncPrimitives()}); | 425 SingleThreadTaskRunnerThreadMode::DEDICATED); |
319 EXPECT_TRUE(task_runner->PostTask( | 426 EXPECT_TRUE(task_runner->PostTask( |
320 FROM_HERE, | 427 FROM_HERE, |
321 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 428 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
322 EXPECT_TRUE(task_runner->PostTask( | 429 EXPECT_TRUE(task_runner->PostTask( |
323 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 430 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
324 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 431 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); |
325 } | 432 } |
326 | 433 |
327 task_running.Wait(); | 434 task_running.Wait(); |
328 CallJoinFromDifferentThread join_from_different_thread( | 435 CallJoinFromDifferentThread join_from_different_thread( |
329 single_thread_task_runner_manager_.get()); | 436 single_thread_task_runner_manager_.get()); |
330 join_from_different_thread.Start(); | 437 join_from_different_thread.Start(); |
331 join_from_different_thread.WaitForRunToStart(); | 438 join_from_different_thread.WaitForRunToStart(); |
332 task_blocking.Signal(); | 439 task_blocking.Signal(); |
333 join_from_different_thread.Join(); | 440 join_from_different_thread.Join(); |
334 } | 441 } |
335 | 442 |
336 #if defined(OS_WIN) | 443 #if defined(OS_WIN) |
337 | 444 |
338 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 445 TEST_P(TaskSchedulerSingleThreadTaskRunnerManagerCommonTest, |
446 COMSTAInitialized) { | |
339 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 447 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
340 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 448 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
341 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | 449 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, GetParam()); |
342 | 450 |
343 com_task_runner->PostTask( | 451 com_task_runner->PostTask( |
344 FROM_HERE, BindOnce([]() { | 452 FROM_HERE, BindOnce([]() { |
345 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 453 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
346 if (SUCCEEDED(hr)) { | 454 if (SUCCEEDED(hr)) { |
347 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 455 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
348 CoUninitialize(); | 456 CoUninitialize(); |
349 } | 457 } |
350 })); | 458 })); |
351 | 459 |
352 task_tracker_.Shutdown(); | 460 task_tracker_.Shutdown(); |
353 } | 461 } |
354 | 462 |
463 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTASameThreadUsed) { | |
gab
2017/05/25 18:47:01
Seems like this is testing an implementation detai
robliao
2017/05/30 20:01:07
This is currently the only reasonable way to verif
| |
464 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | |
465 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | |
466 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
467 SingleThreadTaskRunnerThreadMode::SHARED); | |
468 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | |
469 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | |
470 "B", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, | |
471 SingleThreadTaskRunnerThreadMode::SHARED); | |
472 | |
473 PlatformThreadRef thread_ref_1; | |
474 task_runner_1->PostTask(FROM_HERE, | |
475 BindOnce(&CaptureThreadRef, &thread_ref_1)); | |
476 PlatformThreadRef thread_ref_2; | |
477 task_runner_2->PostTask(FROM_HERE, | |
478 BindOnce(&CaptureThreadRef, &thread_ref_2)); | |
479 | |
480 task_tracker_.Shutdown(); | |
481 | |
482 ASSERT_FALSE(thread_ref_1.is_null()); | |
483 ASSERT_FALSE(thread_ref_2.is_null()); | |
484 EXPECT_EQ(thread_ref_1, thread_ref_2); | |
485 } | |
486 | |
355 namespace { | 487 namespace { |
356 | 488 |
357 const wchar_t* const kTestWindowClassName = | 489 const wchar_t* const kTestWindowClassName = |
358 L"TaskSchedulerSingleThreadTaskRunnerManagerTestWinMessageWindow"; | 490 L"TaskSchedulerSingleThreadTaskRunnerManagerTestWinMessageWindow"; |
359 | 491 |
360 class TaskSchedulerSingleThreadTaskRunnerManagerTestWin | 492 class TaskSchedulerSingleThreadTaskRunnerManagerTestWin |
361 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { | 493 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { |
362 public: | 494 public: |
363 TaskSchedulerSingleThreadTaskRunnerManagerTestWin() = default; | 495 TaskSchedulerSingleThreadTaskRunnerManagerTestWin() = default; |
364 | 496 |
(...skipping 28 matching lines...) Expand all Loading... | |
393 bool register_class_succeeded_ = false; | 525 bool register_class_succeeded_ = false; |
394 | 526 |
395 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 527 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
396 }; | 528 }; |
397 | 529 |
398 } // namespace | 530 } // namespace |
399 | 531 |
400 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 532 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
401 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 533 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
402 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 534 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
403 "A", ThreadPriority::NORMAL, {TaskShutdownBehavior::BLOCK_SHUTDOWN}); | 535 "A", {TaskShutdownBehavior::BLOCK_SHUTDOWN}, |
536 SingleThreadTaskRunnerThreadMode::DEDICATED); | |
gab
2017/05/25 18:47:01
Why isn't this also Common?
robliao
2017/05/30 20:01:07
This uses TaskSchedulerSingleThreadTaskRunnerTestW
| |
404 HWND hwnd = nullptr; | 537 HWND hwnd = nullptr; |
405 // HWNDs process messages on the thread that created them, so we have to | 538 // HWNDs process messages on the thread that created them, so we have to |
406 // create them within the context of the task runner to properly simulate a | 539 // create them within the context of the task runner to properly simulate a |
407 // COM callback. | 540 // COM callback. |
408 com_task_runner->PostTask( | 541 com_task_runner->PostTask( |
409 FROM_HERE, | 542 FROM_HERE, |
410 BindOnce( | 543 BindOnce( |
411 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 544 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, |
412 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 545 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, |
413 Unretained(this), &hwnd)); | 546 Unretained(this), &hwnd)); |
(...skipping 25 matching lines...) Expand all Loading... | |
439 // Start() is called in the test body rather than in SetUp(). | 572 // Start() is called in the test body rather than in SetUp(). |
440 } | 573 } |
441 | 574 |
442 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerStartTest); | 575 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerStartTest); |
443 }; | 576 }; |
444 | 577 |
445 } // namespace | 578 } // namespace |
446 | 579 |
447 // Verify that a task posted before Start() doesn't run until Start() is called. | 580 // Verify that a task posted before Start() doesn't run until Start() is called. |
448 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 581 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, |
449 PostTaskBeforeStart) { | 582 PostTaskBeforeStart) { |
gab
2017/05/25 18:47:01
Why isn't this also Common?
robliao
2017/05/30 20:01:07
See above. This is a different class similar to th
| |
450 AtomicFlag manager_started; | 583 AtomicFlag manager_started; |
451 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 584 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
452 WaitableEvent::InitialState::NOT_SIGNALED); | 585 WaitableEvent::InitialState::NOT_SIGNALED); |
453 single_thread_task_runner_manager_ | 586 single_thread_task_runner_manager_ |
454 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, | 587 ->CreateSingleThreadTaskRunnerWithTraits( |
455 TaskTraits()) | 588 "A", TaskTraits(), SingleThreadTaskRunnerThreadMode::DEDICATED) |
456 ->PostTask( | 589 ->PostTask( |
457 FROM_HERE, | 590 FROM_HERE, |
458 BindOnce( | 591 BindOnce( |
459 [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 592 [](WaitableEvent* task_running, AtomicFlag* manager_started) { |
460 task_running->Signal(); | 593 task_running->Signal(); |
461 | 594 |
462 // The task should not run before Start(). | 595 // The task should not run before Start(). |
463 EXPECT_TRUE(manager_started->IsSet()); | 596 EXPECT_TRUE(manager_started->IsSet()); |
464 }, | 597 }, |
465 Unretained(&task_running), Unretained(&manager_started))); | 598 Unretained(&task_running), Unretained(&manager_started))); |
466 | 599 |
467 // Wait a little bit to make sure that the task isn't scheduled before start. | 600 // Wait a little bit to make sure that the task isn't scheduled before start. |
468 // Note: This test won't catch a case where the task is scheduled between | 601 // Note: This test won't catch a case where the task is scheduled between |
469 // setting |manager_started| and calling Start(). However, we expect the test | 602 // setting |manager_started| and calling Start(). However, we expect the test |
470 // to be flaky if the tested code allows that to happen. | 603 // to be flaky if the tested code allows that to happen. |
471 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 604 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
472 manager_started.Set(); | 605 manager_started.Set(); |
473 single_thread_task_runner_manager_->Start(); | 606 single_thread_task_runner_manager_->Start(); |
474 | 607 |
475 // This should not hang if the task is scheduled after Start(). | 608 // This should not hang if the task is scheduled after Start(). |
476 task_running.Wait(); | 609 task_running.Wait(); |
477 } | 610 } |
478 | 611 |
479 } // namespace internal | 612 } // namespace internal |
480 } // namespace base | 613 } // namespace base |
OLD | NEW |