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" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include <objbase.h> | 25 #include <objbase.h> |
26 | 26 |
27 #include "base/win/current_module.h" | 27 #include "base/win/current_module.h" |
28 #endif // defined(OS_WIN) | 28 #endif // defined(OS_WIN) |
29 | 29 |
30 namespace base { | 30 namespace base { |
31 namespace internal { | 31 namespace internal { |
32 | 32 |
33 namespace { | 33 namespace { |
34 | 34 |
35 enum WorkerPoolType : size_t { | |
36 BACKGROUND_WORKER_POOL = 0, | |
37 FOREGROUND_WORKER_POOL, | |
38 }; | |
39 | |
40 static size_t GetThreadPoolIndexForTraits(const TaskTraits& traits) { | |
41 return traits.priority() == TaskPriority::BACKGROUND ? BACKGROUND_WORKER_POOL | |
42 : FOREGROUND_WORKER_POOL; | |
43 } | |
44 | |
45 std::vector<SchedulerWorkerPoolParams> GetParamsVector() { | |
46 using StandbyThreadPolicy = SchedulerWorkerPoolParams::StandbyThreadPolicy; | |
47 | |
48 std::vector<SchedulerWorkerPoolParams> params_vector; | |
49 | |
50 DCHECK_EQ(BACKGROUND_WORKER_POOL, params_vector.size()); | |
51 params_vector.emplace_back("Background", ThreadPriority::BACKGROUND, | |
52 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); | |
53 | |
54 DCHECK_EQ(FOREGROUND_WORKER_POOL, params_vector.size()); | |
55 params_vector.emplace_back("Foreground", ThreadPriority::NORMAL, | |
56 StandbyThreadPolicy::LAZY, 1U, TimeDelta::Max()); | |
57 | |
58 return params_vector; | |
59 } | |
60 | |
61 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { | 35 class TaskSchedulerSingleThreadTaskRunnerManagerTest : public testing::Test { |
62 public: | 36 public: |
63 TaskSchedulerSingleThreadTaskRunnerManagerTest() | 37 TaskSchedulerSingleThreadTaskRunnerManagerTest() |
64 : service_thread_("TaskSchedulerServiceThread") {} | 38 : service_thread_("TaskSchedulerServiceThread") {} |
65 | 39 |
66 void SetUp() override { | 40 void SetUp() override { |
67 service_thread_.Start(); | 41 service_thread_.Start(); |
68 | |
69 delayed_task_manager_ = | 42 delayed_task_manager_ = |
70 MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); | 43 MakeUnique<DelayedTaskManager>(service_thread_.task_runner()); |
71 single_thread_task_runner_manager_ = | 44 single_thread_task_runner_manager_ = |
72 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( | 45 MakeUnique<SchedulerSingleThreadTaskRunnerManager>( |
73 GetParamsVector(), Bind(&GetThreadPoolIndexForTraits), | |
74 &task_tracker_, delayed_task_manager_.get()); | 46 &task_tracker_, delayed_task_manager_.get()); |
75 StartSingleThreadTaskRunnerManagerFromSetUp(); | 47 StartSingleThreadTaskRunnerManagerFromSetUp(); |
76 } | 48 } |
77 | 49 |
78 void TearDown() override { | 50 void TearDown() override { |
79 TearDownSingleThreadTaskRunnerManager(); | 51 TearDownSingleThreadTaskRunnerManager(); |
80 delayed_task_manager_.reset(); | 52 delayed_task_manager_.reset(); |
81 service_thread_.Stop(); | 53 service_thread_.Stop(); |
82 } | 54 } |
83 | 55 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 void ShouldNotRun() { | 87 void ShouldNotRun() { |
116 ADD_FAILURE() << "Ran a task that shouldn't run."; | 88 ADD_FAILURE() << "Ran a task that shouldn't run."; |
117 } | 89 } |
118 | 90 |
119 } // namespace | 91 } // namespace |
120 | 92 |
121 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { | 93 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, DifferentThreadsUsed) { |
122 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 94 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
123 single_thread_task_runner_manager_ | 95 single_thread_task_runner_manager_ |
124 ->CreateSingleThreadTaskRunnerWithTraits( | 96 ->CreateSingleThreadTaskRunnerWithTraits( |
| 97 "A", ThreadPriority::NORMAL, |
125 TaskTraits().WithShutdownBehavior( | 98 TaskTraits().WithShutdownBehavior( |
126 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 99 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
127 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 100 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
128 single_thread_task_runner_manager_ | 101 single_thread_task_runner_manager_ |
129 ->CreateSingleThreadTaskRunnerWithTraits( | 102 ->CreateSingleThreadTaskRunnerWithTraits( |
| 103 "B", ThreadPriority::NORMAL, |
130 TaskTraits().WithShutdownBehavior( | 104 TaskTraits().WithShutdownBehavior( |
131 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 105 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
132 | 106 |
133 PlatformThreadRef thread_ref_1; | 107 PlatformThreadRef thread_ref_1; |
134 task_runner_1->PostTask(FROM_HERE, | 108 task_runner_1->PostTask(FROM_HERE, |
135 BindOnce(&CaptureThreadRef, &thread_ref_1)); | 109 BindOnce(&CaptureThreadRef, &thread_ref_1)); |
136 PlatformThreadRef thread_ref_2; | 110 PlatformThreadRef thread_ref_2; |
137 task_runner_2->PostTask(FROM_HERE, | 111 task_runner_2->PostTask(FROM_HERE, |
138 BindOnce(&CaptureThreadRef, &thread_ref_2)); | 112 BindOnce(&CaptureThreadRef, &thread_ref_2)); |
139 | 113 |
140 task_tracker_.Shutdown(); | 114 task_tracker_.Shutdown(); |
141 | 115 |
142 ASSERT_FALSE(thread_ref_1.is_null()); | 116 ASSERT_FALSE(thread_ref_1.is_null()); |
143 ASSERT_FALSE(thread_ref_2.is_null()); | 117 ASSERT_FALSE(thread_ref_2.is_null()); |
144 EXPECT_NE(thread_ref_1, thread_ref_2); | 118 EXPECT_NE(thread_ref_1, thread_ref_2); |
145 } | 119 } |
146 | 120 |
147 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { | 121 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PrioritySetCorrectly) { |
148 // Why are events used here instead of the task tracker? | 122 // Why are events used here instead of the task tracker? |
149 // Shutting down can cause priorities to get raised. This means we have to use | 123 // Shutting down can cause priorities to get raised. This means we have to use |
150 // events to determine when a task is run. | 124 // events to determine when a task is run. |
151 scoped_refptr<SingleThreadTaskRunner> task_runner_background = | 125 scoped_refptr<SingleThreadTaskRunner> task_runner_background = |
152 single_thread_task_runner_manager_ | 126 single_thread_task_runner_manager_ |
153 ->CreateSingleThreadTaskRunnerWithTraits( | 127 ->CreateSingleThreadTaskRunnerWithTraits( |
| 128 "Background", ThreadPriority::BACKGROUND, |
154 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); | 129 TaskTraits().WithPriority(TaskPriority::BACKGROUND)); |
155 scoped_refptr<SingleThreadTaskRunner> task_runner_user_visible = | 130 scoped_refptr<SingleThreadTaskRunner> task_runner_normal = |
156 single_thread_task_runner_manager_ | 131 single_thread_task_runner_manager_ |
157 ->CreateSingleThreadTaskRunnerWithTraits( | 132 ->CreateSingleThreadTaskRunnerWithTraits( |
| 133 "Normal", ThreadPriority::NORMAL, |
158 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); | 134 TaskTraits().WithPriority(TaskPriority::USER_VISIBLE)); |
159 scoped_refptr<SingleThreadTaskRunner> task_runner_user_blocking = | |
160 single_thread_task_runner_manager_ | |
161 ->CreateSingleThreadTaskRunnerWithTraits( | |
162 TaskTraits() | |
163 .WithPriority(TaskPriority::USER_BLOCKING) | |
164 .WithShutdownBehavior(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
165 | 135 |
166 ThreadPriority thread_priority_background; | 136 ThreadPriority thread_priority_background; |
167 task_runner_background->PostTask( | 137 task_runner_background->PostTask( |
168 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); | 138 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_background)); |
169 WaitableEvent waitable_event_background( | 139 WaitableEvent waitable_event_background( |
170 WaitableEvent::ResetPolicy::MANUAL, | 140 WaitableEvent::ResetPolicy::MANUAL, |
171 WaitableEvent::InitialState::NOT_SIGNALED); | 141 WaitableEvent::InitialState::NOT_SIGNALED); |
172 task_runner_background->PostTask( | 142 task_runner_background->PostTask( |
173 FROM_HERE, | 143 FROM_HERE, |
174 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); | 144 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_background))); |
175 | 145 |
176 ThreadPriority thread_priority_user_visible; | 146 ThreadPriority thread_priority_normal; |
177 task_runner_user_visible->PostTask( | 147 task_runner_normal->PostTask( |
178 FROM_HERE, | 148 FROM_HERE, BindOnce(&CaptureThreadPriority, &thread_priority_normal)); |
179 BindOnce(&CaptureThreadPriority, &thread_priority_user_visible)); | 149 WaitableEvent waitable_event_normal( |
180 WaitableEvent waitable_event_user_visible( | |
181 WaitableEvent::ResetPolicy::MANUAL, | 150 WaitableEvent::ResetPolicy::MANUAL, |
182 WaitableEvent::InitialState::NOT_SIGNALED); | 151 WaitableEvent::InitialState::NOT_SIGNALED); |
183 task_runner_user_visible->PostTask( | 152 task_runner_normal->PostTask( |
184 FROM_HERE, BindOnce(&WaitableEvent::Signal, | |
185 Unretained(&waitable_event_user_visible))); | |
186 | |
187 ThreadPriority thread_priority_user_blocking; | |
188 task_runner_user_blocking->PostTask( | |
189 FROM_HERE, | 153 FROM_HERE, |
190 BindOnce(&CaptureThreadPriority, &thread_priority_user_blocking)); | 154 BindOnce(&WaitableEvent::Signal, Unretained(&waitable_event_normal))); |
191 WaitableEvent waitable_event_user_blocking( | |
192 WaitableEvent::ResetPolicy::MANUAL, | |
193 WaitableEvent::InitialState::NOT_SIGNALED); | |
194 task_runner_user_blocking->PostTask( | |
195 FROM_HERE, BindOnce(&WaitableEvent::Signal, | |
196 Unretained(&waitable_event_user_blocking))); | |
197 | 155 |
198 waitable_event_background.Wait(); | 156 waitable_event_background.Wait(); |
199 waitable_event_user_visible.Wait(); | 157 waitable_event_normal.Wait(); |
200 waitable_event_user_blocking.Wait(); | |
201 | 158 |
202 if (Lock::HandlesMultipleThreadPriorities()) | 159 if (Lock::HandlesMultipleThreadPriorities()) |
203 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); | 160 EXPECT_EQ(ThreadPriority::BACKGROUND, thread_priority_background); |
204 else | 161 else |
205 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); | 162 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_background); |
206 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_visible); | 163 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_normal); |
207 EXPECT_EQ(ThreadPriority::NORMAL, thread_priority_user_blocking); | |
208 } | 164 } |
209 | 165 |
210 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { | 166 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostTaskAfterShutdown) { |
211 auto task_runner = single_thread_task_runner_manager_ | 167 auto task_runner = single_thread_task_runner_manager_ |
212 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 168 ->CreateSingleThreadTaskRunnerWithTraits( |
| 169 "A", ThreadPriority::NORMAL, TaskTraits()); |
213 task_tracker_.Shutdown(); | 170 task_tracker_.Shutdown(); |
214 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); | 171 EXPECT_FALSE(task_runner->PostTask(FROM_HERE, BindOnce(&ShouldNotRun))); |
215 } | 172 } |
216 | 173 |
217 // Verify that a Task runs shortly after its delay expires. | 174 // Verify that a Task runs shortly after its delay expires. |
218 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { | 175 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, PostDelayedTask) { |
219 TimeTicks start_time = TimeTicks::Now(); | 176 TimeTicks start_time = TimeTicks::Now(); |
220 | 177 |
221 // Post a task with a short delay. | 178 // Post a task with a short delay. |
222 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, | 179 WaitableEvent task_ran(WaitableEvent::ResetPolicy::MANUAL, |
223 WaitableEvent::InitialState::NOT_SIGNALED); | 180 WaitableEvent::InitialState::NOT_SIGNALED); |
224 auto task_runner = single_thread_task_runner_manager_ | 181 auto task_runner = single_thread_task_runner_manager_ |
225 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()); | 182 ->CreateSingleThreadTaskRunnerWithTraits( |
| 183 "A", ThreadPriority::NORMAL, TaskTraits()); |
226 EXPECT_TRUE(task_runner->PostDelayedTask( | 184 EXPECT_TRUE(task_runner->PostDelayedTask( |
227 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), | 185 FROM_HERE, BindOnce(&WaitableEvent::Signal, Unretained(&task_ran)), |
228 TestTimeouts::tiny_timeout())); | 186 TestTimeouts::tiny_timeout())); |
229 | 187 |
230 // Wait until the task runs. | 188 // Wait until the task runs. |
231 task_ran.Wait(); | 189 task_ran.Wait(); |
232 | 190 |
233 // Expect the task to run after its delay expires, but not more than 250 ms | 191 // Expect the task to run after its delay expires, but not more than 250 ms |
234 // after that. | 192 // after that. |
235 const TimeDelta actual_delay = TimeTicks::Now() - start_time; | 193 const TimeDelta actual_delay = TimeTicks::Now() - start_time; |
236 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); | 194 EXPECT_GE(actual_delay, TestTimeouts::tiny_timeout()); |
237 EXPECT_LT(actual_delay, | 195 EXPECT_LT(actual_delay, |
238 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); | 196 TimeDelta::FromMilliseconds(250) + TestTimeouts::tiny_timeout()); |
239 } | 197 } |
240 | 198 |
241 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, | 199 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, |
242 RunsTasksOnCurrentThread) { | 200 RunsTasksOnCurrentThread) { |
243 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = | 201 scoped_refptr<SingleThreadTaskRunner> task_runner_1 = |
244 single_thread_task_runner_manager_ | 202 single_thread_task_runner_manager_ |
245 ->CreateSingleThreadTaskRunnerWithTraits( | 203 ->CreateSingleThreadTaskRunnerWithTraits( |
| 204 "A", ThreadPriority::NORMAL, |
246 TaskTraits().WithShutdownBehavior( | 205 TaskTraits().WithShutdownBehavior( |
247 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 206 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
248 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = | 207 scoped_refptr<SingleThreadTaskRunner> task_runner_2 = |
249 single_thread_task_runner_manager_ | 208 single_thread_task_runner_manager_ |
250 ->CreateSingleThreadTaskRunnerWithTraits( | 209 ->CreateSingleThreadTaskRunnerWithTraits( |
| 210 "B", ThreadPriority::NORMAL, |
251 TaskTraits().WithShutdownBehavior( | 211 TaskTraits().WithShutdownBehavior( |
252 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 212 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
253 | 213 |
254 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); | 214 EXPECT_FALSE(task_runner_1->RunsTasksOnCurrentThread()); |
255 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); | 215 EXPECT_FALSE(task_runner_2->RunsTasksOnCurrentThread()); |
256 | 216 |
257 task_runner_1->PostTask( | 217 task_runner_1->PostTask( |
258 FROM_HERE, BindOnce( | 218 FROM_HERE, BindOnce( |
259 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, | 219 [](scoped_refptr<SingleThreadTaskRunner> task_runner_1, |
260 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { | 220 scoped_refptr<SingleThreadTaskRunner> task_runner_2) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 // Exercises the codepath where the workers are unavailable for unregistration | 284 // Exercises the codepath where the workers are unavailable for unregistration |
325 // because of a Join call. | 285 // because of a Join call. |
326 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 286 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
327 WaitableEvent::InitialState::NOT_SIGNALED); | 287 WaitableEvent::InitialState::NOT_SIGNALED); |
328 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 288 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
329 WaitableEvent::InitialState::NOT_SIGNALED); | 289 WaitableEvent::InitialState::NOT_SIGNALED); |
330 | 290 |
331 { | 291 { |
332 auto task_runner = single_thread_task_runner_manager_ | 292 auto task_runner = single_thread_task_runner_manager_ |
333 ->CreateSingleThreadTaskRunnerWithTraits( | 293 ->CreateSingleThreadTaskRunnerWithTraits( |
| 294 "A", ThreadPriority::NORMAL, |
334 TaskTraits().WithBaseSyncPrimitives()); | 295 TaskTraits().WithBaseSyncPrimitives()); |
335 EXPECT_TRUE(task_runner->PostTask( | 296 EXPECT_TRUE(task_runner->PostTask( |
336 FROM_HERE, | 297 FROM_HERE, |
337 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 298 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
338 EXPECT_TRUE(task_runner->PostTask( | 299 EXPECT_TRUE(task_runner->PostTask( |
339 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 300 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
340 } | 301 } |
341 | 302 |
342 task_running.Wait(); | 303 task_running.Wait(); |
343 CallJoinFromDifferentThread join_from_different_thread( | 304 CallJoinFromDifferentThread join_from_different_thread( |
344 single_thread_task_runner_manager_.get()); | 305 single_thread_task_runner_manager_.get()); |
345 join_from_different_thread.Start(); | 306 join_from_different_thread.Start(); |
346 join_from_different_thread.WaitForRunToStart(); | 307 join_from_different_thread.WaitForRunToStart(); |
347 task_blocking.Signal(); | 308 task_blocking.Signal(); |
348 join_from_different_thread.Join(); | 309 join_from_different_thread.Join(); |
349 } | 310 } |
350 | 311 |
351 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, | 312 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerJoinTest, |
352 ConcurrentJoinExtraSkippedTask) { | 313 ConcurrentJoinExtraSkippedTask) { |
353 // Tests to make sure that tasks are properly cleaned up at Join, allowing | 314 // Tests to make sure that tasks are properly cleaned up at Join, allowing |
354 // SingleThreadTaskRunners to unregister themselves. | 315 // SingleThreadTaskRunners to unregister themselves. |
355 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 316 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
356 WaitableEvent::InitialState::NOT_SIGNALED); | 317 WaitableEvent::InitialState::NOT_SIGNALED); |
357 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, | 318 WaitableEvent task_blocking(WaitableEvent::ResetPolicy::MANUAL, |
358 WaitableEvent::InitialState::NOT_SIGNALED); | 319 WaitableEvent::InitialState::NOT_SIGNALED); |
359 | 320 |
360 { | 321 { |
361 auto task_runner = single_thread_task_runner_manager_ | 322 auto task_runner = single_thread_task_runner_manager_ |
362 ->CreateSingleThreadTaskRunnerWithTraits( | 323 ->CreateSingleThreadTaskRunnerWithTraits( |
| 324 "A", ThreadPriority::NORMAL, |
363 TaskTraits().WithBaseSyncPrimitives()); | 325 TaskTraits().WithBaseSyncPrimitives()); |
364 EXPECT_TRUE(task_runner->PostTask( | 326 EXPECT_TRUE(task_runner->PostTask( |
365 FROM_HERE, | 327 FROM_HERE, |
366 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); | 328 BindOnce(&WaitableEvent::Signal, Unretained(&task_running)))); |
367 EXPECT_TRUE(task_runner->PostTask( | 329 EXPECT_TRUE(task_runner->PostTask( |
368 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); | 330 FROM_HERE, BindOnce(&WaitableEvent::Wait, Unretained(&task_blocking)))); |
369 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); | 331 EXPECT_TRUE(task_runner->PostTask(FROM_HERE, BindOnce(&DoNothing))); |
370 } | 332 } |
371 | 333 |
372 task_running.Wait(); | 334 task_running.Wait(); |
373 CallJoinFromDifferentThread join_from_different_thread( | 335 CallJoinFromDifferentThread join_from_different_thread( |
374 single_thread_task_runner_manager_.get()); | 336 single_thread_task_runner_manager_.get()); |
375 join_from_different_thread.Start(); | 337 join_from_different_thread.Start(); |
376 join_from_different_thread.WaitForRunToStart(); | 338 join_from_different_thread.WaitForRunToStart(); |
377 task_blocking.Signal(); | 339 task_blocking.Signal(); |
378 join_from_different_thread.Join(); | 340 join_from_different_thread.Join(); |
379 } | 341 } |
380 | 342 |
381 #if defined(OS_WIN) | 343 #if defined(OS_WIN) |
382 | 344 |
383 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { | 345 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTest, COMSTAInitialized) { |
384 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 346 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
385 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 347 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 348 "A", ThreadPriority::NORMAL, |
386 TaskTraits().WithShutdownBehavior( | 349 TaskTraits().WithShutdownBehavior( |
387 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 350 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
388 | 351 |
389 com_task_runner->PostTask( | 352 com_task_runner->PostTask( |
390 FROM_HERE, Bind([]() { | 353 FROM_HERE, BindOnce([]() { |
391 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); | 354 HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); |
392 if (SUCCEEDED(hr)) { | 355 if (SUCCEEDED(hr)) { |
393 ADD_FAILURE() << "COM STA was not initialized on this thread"; | 356 ADD_FAILURE() << "COM STA was not initialized on this thread"; |
394 CoUninitialize(); | 357 CoUninitialize(); |
395 } | 358 } |
396 })); | 359 })); |
397 | 360 |
398 task_tracker_.Shutdown(); | 361 task_tracker_.Shutdown(); |
399 } | 362 } |
400 | 363 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 bool register_class_succeeded_ = false; | 402 bool register_class_succeeded_ = false; |
440 | 403 |
441 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); | 404 DISALLOW_COPY_AND_ASSIGN(TaskSchedulerSingleThreadTaskRunnerManagerTestWin); |
442 }; | 405 }; |
443 | 406 |
444 } // namespace | 407 } // namespace |
445 | 408 |
446 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { | 409 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerTestWin, PumpsMessages) { |
447 scoped_refptr<SingleThreadTaskRunner> com_task_runner = | 410 scoped_refptr<SingleThreadTaskRunner> com_task_runner = |
448 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( | 411 single_thread_task_runner_manager_->CreateCOMSTATaskRunnerWithTraits( |
| 412 "A", ThreadPriority::NORMAL, |
449 TaskTraits().WithShutdownBehavior( | 413 TaskTraits().WithShutdownBehavior( |
450 TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 414 TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
451 HWND hwnd = nullptr; | 415 HWND hwnd = nullptr; |
452 // HWNDs process messages on the thread that created them, so we have to | 416 // HWNDs process messages on the thread that created them, so we have to |
453 // create them within the context of the task runner to properly simulate a | 417 // create them within the context of the task runner to properly simulate a |
454 // COM callback. | 418 // COM callback. |
455 com_task_runner->PostTask( | 419 com_task_runner->PostTask( |
456 FROM_HERE, | 420 FROM_HERE, |
457 Bind([](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, | 421 BindOnce( |
458 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, | 422 [](TaskSchedulerSingleThreadTaskRunnerManagerTestWin* test_harness, |
459 Unretained(this), &hwnd)); | 423 HWND* hwnd) { *hwnd = test_harness->CreateTestWindow(); }, |
| 424 Unretained(this), &hwnd)); |
460 | 425 |
461 task_tracker_.Flush(); | 426 task_tracker_.Flush(); |
462 | 427 |
463 ASSERT_NE(hwnd, nullptr); | 428 ASSERT_NE(hwnd, nullptr); |
464 // If the message pump isn't running, we will hang here. This simulates how | 429 // If the message pump isn't running, we will hang here. This simulates how |
465 // COM would receive a callback with its own message HWND. | 430 // COM would receive a callback with its own message HWND. |
466 SendMessage(hwnd, WM_USER, 0, 0); | 431 SendMessage(hwnd, WM_USER, 0, 0); |
467 | 432 |
468 com_task_runner->PostTask( | 433 com_task_runner->PostTask( |
469 FROM_HERE, Bind([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); | 434 FROM_HERE, BindOnce([](HWND hwnd) { ::DestroyWindow(hwnd); }, hwnd)); |
470 | 435 |
471 task_tracker_.Shutdown(); | 436 task_tracker_.Shutdown(); |
472 } | 437 } |
473 | 438 |
474 #endif // defined(OS_WIN) | 439 #endif // defined(OS_WIN) |
475 | 440 |
476 namespace { | 441 namespace { |
477 | 442 |
478 class TaskSchedulerSingleThreadTaskRunnerManagerStartTest | 443 class TaskSchedulerSingleThreadTaskRunnerManagerStartTest |
479 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { | 444 : public TaskSchedulerSingleThreadTaskRunnerManagerTest { |
(...skipping 10 matching lines...) Expand all Loading... |
490 | 455 |
491 } // namespace | 456 } // namespace |
492 | 457 |
493 // Verify that a task posted before Start() doesn't run until Start() is called. | 458 // Verify that a task posted before Start() doesn't run until Start() is called. |
494 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, | 459 TEST_F(TaskSchedulerSingleThreadTaskRunnerManagerStartTest, |
495 PostTaskBeforeStart) { | 460 PostTaskBeforeStart) { |
496 AtomicFlag manager_started; | 461 AtomicFlag manager_started; |
497 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, | 462 WaitableEvent task_running(WaitableEvent::ResetPolicy::MANUAL, |
498 WaitableEvent::InitialState::NOT_SIGNALED); | 463 WaitableEvent::InitialState::NOT_SIGNALED); |
499 single_thread_task_runner_manager_ | 464 single_thread_task_runner_manager_ |
500 ->CreateSingleThreadTaskRunnerWithTraits(TaskTraits()) | 465 ->CreateSingleThreadTaskRunnerWithTraits("A", ThreadPriority::NORMAL, |
| 466 TaskTraits()) |
501 ->PostTask( | 467 ->PostTask( |
502 FROM_HERE, | 468 FROM_HERE, |
503 Bind( | 469 BindOnce( |
504 [](WaitableEvent* task_running, AtomicFlag* manager_started) { | 470 [](WaitableEvent* task_running, AtomicFlag* manager_started) { |
505 task_running->Signal(); | 471 task_running->Signal(); |
506 | 472 |
507 // The task should not run before Start(). | 473 // The task should not run before Start(). |
508 EXPECT_TRUE(manager_started->IsSet()); | 474 EXPECT_TRUE(manager_started->IsSet()); |
509 }, | 475 }, |
510 Unretained(&task_running), Unretained(&manager_started))); | 476 Unretained(&task_running), Unretained(&manager_started))); |
511 | 477 |
512 // Wait a little bit to make sure that the task isn't scheduled before start. | 478 // Wait a little bit to make sure that the task isn't scheduled before start. |
513 // Note: This test won't catch a case where the task is scheduled between | 479 // Note: This test won't catch a case where the task is scheduled between |
514 // setting |manager_started| and calling Start(). However, we expect the test | 480 // setting |manager_started| and calling Start(). However, we expect the test |
515 // to be flaky if the tested code allows that to happen. | 481 // to be flaky if the tested code allows that to happen. |
516 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); | 482 PlatformThread::Sleep(TestTimeouts::tiny_timeout()); |
517 manager_started.Set(); | 483 manager_started.Set(); |
518 single_thread_task_runner_manager_->Start(); | 484 single_thread_task_runner_manager_->Start(); |
519 | 485 |
520 // This should not hang if the task is scheduled after Start(). | 486 // This should not hang if the task is scheduled after Start(). |
521 task_running.Wait(); | 487 task_running.Wait(); |
522 } | 488 } |
523 | 489 |
524 } // namespace internal | 490 } // namespace internal |
525 } // namespace base | 491 } // namespace base |
OLD | NEW |