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/task_tracker.h" | 5 #include "base/task_scheduler/task_tracker.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/macros.h" | 14 #include "base/macros.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/memory/ref_counted.h" | 16 #include "base/memory/ref_counted.h" |
17 #include "base/sequence_token.h" | |
17 #include "base/sequenced_task_runner.h" | 18 #include "base/sequenced_task_runner.h" |
18 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
19 #include "base/synchronization/waitable_event.h" | 20 #include "base/synchronization/waitable_event.h" |
20 #include "base/task_scheduler/scheduler_lock.h" | 21 #include "base/task_scheduler/scheduler_lock.h" |
22 #include "base/task_scheduler/sequence.h" | |
21 #include "base/task_scheduler/task.h" | 23 #include "base/task_scheduler/task.h" |
22 #include "base/task_scheduler/task_traits.h" | 24 #include "base/task_scheduler/task_traits.h" |
23 #include "base/task_scheduler/test_utils.h" | 25 #include "base/task_scheduler/test_utils.h" |
24 #include "base/test/test_simple_task_runner.h" | 26 #include "base/test/test_simple_task_runner.h" |
25 #include "base/threading/platform_thread.h" | 27 #include "base/threading/platform_thread.h" |
26 #include "base/threading/sequenced_task_runner_handle.h" | 28 #include "base/threading/sequenced_task_runner_handle.h" |
27 #include "base/threading/simple_thread.h" | 29 #include "base/threading/simple_thread.h" |
28 #include "base/threading/thread_restrictions.h" | 30 #include "base/threading/thread_restrictions.h" |
29 #include "base/threading/thread_task_runner_handle.h" | 31 #include "base/threading/thread_task_runner_handle.h" |
30 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
31 | 33 |
32 namespace base { | 34 namespace base { |
33 namespace internal { | 35 namespace internal { |
34 | 36 |
35 namespace { | 37 namespace { |
36 | 38 |
37 constexpr size_t kLoadTestNumIterations = 100; | 39 constexpr size_t kLoadTestNumIterations = 100; |
38 | 40 |
41 scoped_refptr<Sequence> CreateSequenceWithTask(std::unique_ptr<Task> task) { | |
42 scoped_refptr<Sequence> sequence(new Sequence); | |
43 sequence->PushTask(std::move(task)); | |
44 return sequence; | |
45 } | |
46 | |
39 // Calls TaskTracker::Shutdown() asynchronously. | 47 // Calls TaskTracker::Shutdown() asynchronously. |
40 class ThreadCallingShutdown : public SimpleThread { | 48 class ThreadCallingShutdown : public SimpleThread { |
41 public: | 49 public: |
42 explicit ThreadCallingShutdown(TaskTracker* tracker) | 50 explicit ThreadCallingShutdown(TaskTracker* tracker) |
43 : SimpleThread("ThreadCallingShutdown"), | 51 : SimpleThread("ThreadCallingShutdown"), |
44 tracker_(tracker), | 52 tracker_(tracker), |
45 has_returned_(WaitableEvent::ResetPolicy::MANUAL, | 53 has_returned_(WaitableEvent::ResetPolicy::MANUAL, |
46 WaitableEvent::InitialState::NOT_SIGNALED) {} | 54 WaitableEvent::InitialState::NOT_SIGNALED) {} |
47 | 55 |
48 // Returns true once the async call to Shutdown() has returned. | 56 // Returns true once the async call to Shutdown() has returned. |
(...skipping 13 matching lines...) Expand all Loading... | |
62 | 70 |
63 class ThreadPostingAndRunningTask : public SimpleThread { | 71 class ThreadPostingAndRunningTask : public SimpleThread { |
64 public: | 72 public: |
65 enum class Action { | 73 enum class Action { |
66 WILL_POST, | 74 WILL_POST, |
67 RUN, | 75 RUN, |
68 WILL_POST_AND_RUN, | 76 WILL_POST_AND_RUN, |
69 }; | 77 }; |
70 | 78 |
71 ThreadPostingAndRunningTask(TaskTracker* tracker, | 79 ThreadPostingAndRunningTask(TaskTracker* tracker, |
72 const Task* task, | 80 scoped_refptr<Sequence> sequence, |
73 Action action, | 81 Action action, |
74 bool expect_post_succeeds) | 82 bool expect_post_succeeds) |
75 : SimpleThread("ThreadPostingAndRunningTask"), | 83 : SimpleThread("ThreadPostingAndRunningTask"), |
76 tracker_(tracker), | 84 tracker_(tracker), |
77 task_(task), | 85 sequence_(std::move(sequence)), |
78 action_(action), | 86 action_(action), |
79 expect_post_succeeds_(expect_post_succeeds) {} | 87 expect_post_succeeds_(expect_post_succeeds) {} |
80 | 88 |
81 private: | 89 private: |
82 void Run() override { | 90 void Run() override { |
83 bool post_succeeded = true; | 91 bool post_succeeded = true; |
84 if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { | 92 if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) { |
85 post_succeeded = tracker_->WillPostTask(task_); | 93 post_succeeded = tracker_->WillPostTask(sequence_->PeekTask()); |
86 EXPECT_EQ(expect_post_succeeds_, post_succeeded); | 94 EXPECT_EQ(expect_post_succeeds_, post_succeeded); |
87 } | 95 } |
88 if (post_succeeded && | 96 if (post_succeeded && |
89 (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { | 97 (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) { |
90 tracker_->RunTask(task_); | 98 tracker_->RunNextTaskInSequence(sequence_.get()); |
91 } | 99 } |
92 } | 100 } |
93 | 101 |
94 TaskTracker* const tracker_; | 102 TaskTracker* const tracker_; |
95 const Task* const task_; | 103 const scoped_refptr<Sequence> sequence_; |
96 const Action action_; | 104 const Action action_; |
97 const bool expect_post_succeeds_; | 105 const bool expect_post_succeeds_; |
98 | 106 |
99 DISALLOW_COPY_AND_ASSIGN(ThreadPostingAndRunningTask); | 107 DISALLOW_COPY_AND_ASSIGN(ThreadPostingAndRunningTask); |
100 }; | 108 }; |
101 | 109 |
102 class ScopedSetSingletonAllowed { | 110 class ScopedSetSingletonAllowed { |
103 public: | 111 public: |
104 ScopedSetSingletonAllowed(bool singleton_allowed) | 112 ScopedSetSingletonAllowed(bool singleton_allowed) |
105 : previous_value_( | 113 : previous_value_( |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 } // namespace | 198 } // namespace |
191 | 199 |
192 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { | 200 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunBeforeShutdown) { |
193 std::unique_ptr<Task> task(CreateTask(GetParam())); | 201 std::unique_ptr<Task> task(CreateTask(GetParam())); |
194 | 202 |
195 // Inform |task_tracker_| that |task| will be posted. | 203 // Inform |task_tracker_| that |task| will be posted. |
196 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 204 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
197 | 205 |
198 // Run the task. | 206 // Run the task. |
199 EXPECT_EQ(0U, NumTasksExecuted()); | 207 EXPECT_EQ(0U, NumTasksExecuted()); |
200 tracker_.RunTask(task.get()); | 208 tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
201 EXPECT_EQ(1U, NumTasksExecuted()); | 209 EXPECT_EQ(1U, NumTasksExecuted()); |
202 | 210 |
203 // Shutdown() shouldn't block. | 211 // Shutdown() shouldn't block. |
204 tracker_.Shutdown(); | 212 tracker_.Shutdown(); |
205 } | 213 } |
206 | 214 |
207 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { | 215 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) { |
208 // Create a task that will block until |event| is signaled. | 216 // Create a task that will block until |event| is signaled. |
209 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC, | 217 WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC, |
210 WaitableEvent::InitialState::NOT_SIGNALED); | 218 WaitableEvent::InitialState::NOT_SIGNALED); |
211 std::unique_ptr<Task> blocked_task( | 219 std::unique_ptr<Task> blocked_task( |
212 new Task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), | 220 new Task(FROM_HERE, Bind(&WaitableEvent::Wait, Unretained(&event)), |
213 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 221 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
214 | 222 |
215 // Inform |task_tracker_| that |blocked_task| will be posted. | 223 // Inform |task_tracker_| that |blocked_task| will be posted. |
216 EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get())); | 224 EXPECT_TRUE(tracker_.WillPostTask(blocked_task.get())); |
217 | 225 |
218 // Run the task asynchronouly. | 226 // Run the task asynchronouly. |
219 ThreadPostingAndRunningTask thread_running_task( | 227 ThreadPostingAndRunningTask thread_running_task( |
220 &tracker_, blocked_task.get(), ThreadPostingAndRunningTask::Action::RUN, | 228 &tracker_, CreateSequenceWithTask(std::move(blocked_task)), |
221 false); | 229 ThreadPostingAndRunningTask::Action::RUN, false); |
222 thread_running_task.Start(); | 230 thread_running_task.Start(); |
223 | 231 |
224 // Initiate shutdown while the task is running. | 232 // Initiate shutdown while the task is running. |
225 CallShutdownAsync(); | 233 CallShutdownAsync(); |
226 | 234 |
227 if (GetParam() == TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) { | 235 if (GetParam() == TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) { |
228 // Shutdown should complete even with a CONTINUE_ON_SHUTDOWN in progress. | 236 // Shutdown should complete even with a CONTINUE_ON_SHUTDOWN in progress. |
229 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 237 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
230 } else { | 238 } else { |
231 // Shutdown should block with any non CONTINUE_ON_SHUTDOWN task in progress. | 239 // Shutdown should block with any non CONTINUE_ON_SHUTDOWN task in progress. |
(...skipping 20 matching lines...) Expand all Loading... | |
252 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 260 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
253 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 261 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
254 | 262 |
255 // Call Shutdown() asynchronously. | 263 // Call Shutdown() asynchronously. |
256 CallShutdownAsync(); | 264 CallShutdownAsync(); |
257 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 265 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
258 | 266 |
259 // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it | 267 // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it |
260 // should be discarded. | 268 // should be discarded. |
261 EXPECT_EQ(0U, NumTasksExecuted()); | 269 EXPECT_EQ(0U, NumTasksExecuted()); |
262 tracker_.RunTask(task.get()); | 270 tracker_.RunNextTaskInSequence(CreateSequenceWithTask(std::move(task)).get()); |
263 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 1U : 0U, | 271 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 1U : 0U, |
264 NumTasksExecuted()); | 272 NumTasksExecuted()); |
265 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 273 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
266 | 274 |
267 // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. | 275 // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task. |
268 tracker_.RunTask(block_shutdown_task.get()); | 276 tracker_.RunNextTaskInSequence( |
277 CreateSequenceWithTask(std::move(block_shutdown_task)).get()); | |
269 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, | 278 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
270 NumTasksExecuted()); | 279 NumTasksExecuted()); |
271 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 280 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
272 } | 281 } |
273 | 282 |
274 TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { | 283 TEST_P(TaskSchedulerTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) { |
275 // Inform |task_tracker_| that a task will be posted. | 284 // Inform |task_tracker_| that a task will be posted. |
276 std::unique_ptr<Task> task(CreateTask(GetParam())); | 285 std::unique_ptr<Task> task(CreateTask(GetParam())); |
277 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 286 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
278 | 287 |
279 // Call Shutdown() asynchronously. | 288 // Call Shutdown() asynchronously. |
280 CallShutdownAsync(); | 289 CallShutdownAsync(); |
281 EXPECT_EQ(0U, NumTasksExecuted()); | 290 EXPECT_EQ(0U, NumTasksExecuted()); |
282 | 291 |
283 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { | 292 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { |
284 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 293 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
285 | 294 |
286 // Run the task to unblock shutdown. | 295 // Run the task to unblock shutdown. |
287 tracker_.RunTask(task.get()); | 296 tracker_.RunNextTaskInSequence( |
297 CreateSequenceWithTask(std::move(task)).get()); | |
288 EXPECT_EQ(1U, NumTasksExecuted()); | 298 EXPECT_EQ(1U, NumTasksExecuted()); |
289 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 299 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
290 | 300 |
291 // It is not possible to test running a BLOCK_SHUTDOWN task posted before | 301 // It is not possible to test running a BLOCK_SHUTDOWN task posted before |
292 // shutdown after shutdown because Shutdown() won't return if there are | 302 // shutdown after shutdown because Shutdown() won't return if there are |
293 // pending BLOCK_SHUTDOWN tasks. | 303 // pending BLOCK_SHUTDOWN tasks. |
294 } else { | 304 } else { |
295 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 305 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
296 | 306 |
297 // The task shouldn't be allowed to run after shutdown. | 307 // The task shouldn't be allowed to run after shutdown. |
298 tracker_.RunTask(task.get()); | 308 tracker_.RunNextTaskInSequence( |
309 CreateSequenceWithTask(std::move(task)).get()); | |
299 EXPECT_EQ(0U, NumTasksExecuted()); | 310 EXPECT_EQ(0U, NumTasksExecuted()); |
300 } | 311 } |
301 } | 312 } |
302 | 313 |
303 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { | 314 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAndRunDuringShutdown) { |
304 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 315 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
305 // block shutdown. | 316 // block shutdown. |
306 std::unique_ptr<Task> block_shutdown_task( | 317 std::unique_ptr<Task> block_shutdown_task( |
307 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 318 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
308 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 319 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
309 | 320 |
310 // Call Shutdown() asynchronously. | 321 // Call Shutdown() asynchronously. |
311 CallShutdownAsync(); | 322 CallShutdownAsync(); |
312 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 323 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
313 | 324 |
314 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { | 325 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { |
315 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted. | 326 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted. |
316 std::unique_ptr<Task> task(CreateTask(GetParam())); | 327 std::unique_ptr<Task> task(CreateTask(GetParam())); |
317 EXPECT_TRUE(tracker_.WillPostTask(task.get())); | 328 EXPECT_TRUE(tracker_.WillPostTask(task.get())); |
318 | 329 |
319 // Run the BLOCK_SHUTDOWN task. | 330 // Run the BLOCK_SHUTDOWN task. |
320 EXPECT_EQ(0U, NumTasksExecuted()); | 331 EXPECT_EQ(0U, NumTasksExecuted()); |
321 tracker_.RunTask(task.get()); | 332 tracker_.RunNextTaskInSequence( |
333 CreateSequenceWithTask(std::move(task)).get()); | |
322 EXPECT_EQ(1U, NumTasksExecuted()); | 334 EXPECT_EQ(1U, NumTasksExecuted()); |
323 } else { | 335 } else { |
324 // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. | 336 // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task. |
325 std::unique_ptr<Task> task(CreateTask(GetParam())); | 337 std::unique_ptr<Task> task(CreateTask(GetParam())); |
326 EXPECT_FALSE(tracker_.WillPostTask(task.get())); | 338 EXPECT_FALSE(tracker_.WillPostTask(task.get())); |
327 | 339 |
328 // Don't try to run the task, because it wasn't allowed to be posted. | 340 // Don't try to run the task, because it wasn't allowed to be posted. |
329 } | 341 } |
330 | 342 |
331 // Unblock shutdown by running |block_shutdown_task|. | 343 // Unblock shutdown by running |block_shutdown_task|. |
332 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 344 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
333 tracker_.RunTask(block_shutdown_task.get()); | 345 tracker_.RunNextTaskInSequence( |
346 CreateSequenceWithTask(std::move(block_shutdown_task)).get()); | |
334 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, | 347 EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U, |
335 NumTasksExecuted()); | 348 NumTasksExecuted()); |
336 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 349 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
337 } | 350 } |
338 | 351 |
339 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAfterShutdown) { | 352 TEST_P(TaskSchedulerTaskTrackerTest, WillPostAfterShutdown) { |
340 tracker_.Shutdown(); | 353 tracker_.Shutdown(); |
341 | 354 |
342 std::unique_ptr<Task> task(CreateTask(GetParam())); | 355 std::unique_ptr<Task> task(CreateTask(GetParam())); |
343 | 356 |
344 // |task_tracker_| shouldn't allow a task to be posted after shutdown. | 357 // |task_tracker_| shouldn't allow a task to be posted after shutdown. |
345 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { | 358 if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) { |
346 EXPECT_DCHECK_DEATH({ tracker_.WillPostTask(task.get()); }, ""); | 359 EXPECT_DCHECK_DEATH({ tracker_.WillPostTask(task.get()); }, ""); |
347 } else { | 360 } else { |
348 EXPECT_FALSE(tracker_.WillPostTask(task.get())); | 361 EXPECT_FALSE(tracker_.WillPostTask(task.get())); |
349 } | 362 } |
350 } | 363 } |
351 | 364 |
352 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can | 365 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can |
353 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't. | 366 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't. |
354 TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { | 367 TEST_P(TaskSchedulerTaskTrackerTest, SingletonAllowed) { |
355 const bool can_use_singletons = | 368 const bool can_use_singletons = |
356 (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); | 369 (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN); |
357 | 370 |
358 TaskTracker tracker; | 371 TaskTracker tracker; |
359 Task task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), | 372 std::unique_ptr<Task> task( |
360 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta()); | 373 new Task(FROM_HERE, Bind(&ThreadRestrictions::AssertSingletonAllowed), |
361 EXPECT_TRUE(tracker.WillPostTask(&task)); | 374 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
375 EXPECT_TRUE(tracker.WillPostTask(task.get())); | |
362 | 376 |
363 // Set the singleton allowed bit to the opposite of what it is expected to be | 377 // Set the singleton allowed bit to the opposite of what it is expected to be |
364 // when |tracker| runs |task| to verify that |tracker| actually sets the | 378 // when |tracker| runs |task| to verify that |tracker| actually sets the |
365 // correct value. | 379 // correct value. |
366 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); | 380 ScopedSetSingletonAllowed scoped_singleton_allowed(!can_use_singletons); |
367 | 381 |
368 // Running the task should fail iff the task isn't allowed to use singletons. | 382 // Running the task should fail iff the task isn't allowed to use singletons. |
369 if (can_use_singletons) { | 383 if (can_use_singletons) { |
370 tracker.RunTask(&task); | 384 tracker.RunNextTaskInSequence( |
385 CreateSequenceWithTask(std::move(task)).get()); | |
371 } else { | 386 } else { |
372 EXPECT_DCHECK_DEATH({ tracker.RunTask(&task); }, ""); | 387 EXPECT_DCHECK_DEATH( |
388 { | |
389 tracker.RunNextTaskInSequence( | |
390 CreateSequenceWithTask(std::move(task)).get()); | |
391 }, | |
392 ""); | |
373 } | 393 } |
374 } | 394 } |
375 | 395 |
376 static void RunTaskRunnerHandleVerificationTask(TaskTracker* tracker, | 396 static void RunTaskRunnerHandleVerificationTask( |
377 const Task* verify_task) { | 397 TaskTracker* tracker, |
398 std::unique_ptr<Task> verify_task) { | |
378 // Pretend |verify_task| is posted to respect TaskTracker's contract. | 399 // Pretend |verify_task| is posted to respect TaskTracker's contract. |
379 EXPECT_TRUE(tracker->WillPostTask(verify_task)); | 400 EXPECT_TRUE(tracker->WillPostTask(verify_task.get())); |
380 | 401 |
381 // Confirm that the test conditions are right (no TaskRunnerHandles set | 402 // Confirm that the test conditions are right (no TaskRunnerHandles set |
382 // already). | 403 // already). |
383 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 404 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
384 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 405 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
385 | 406 |
386 tracker->RunTask(verify_task); | 407 tracker->RunNextTaskInSequence( |
408 CreateSequenceWithTask(std::move(verify_task)).get()); | |
387 | 409 |
388 // TaskRunnerHandle state is reset outside of task's scope. | 410 // TaskRunnerHandle state is reset outside of task's scope. |
389 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 411 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
390 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 412 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
391 } | 413 } |
392 | 414 |
393 static void VerifyNoTaskRunnerHandle() { | 415 static void VerifyNoTaskRunnerHandle() { |
394 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 416 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
395 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); | 417 EXPECT_FALSE(SequencedTaskRunnerHandle::IsSet()); |
396 } | 418 } |
397 | 419 |
398 TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { | 420 TEST_P(TaskSchedulerTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) { |
399 // Create a task that will verify that TaskRunnerHandles are not set in its | 421 // Create a task that will verify that TaskRunnerHandles are not set in its |
400 // scope per no TaskRunner ref being set to it. | 422 // scope per no TaskRunner ref being set to it. |
401 std::unique_ptr<Task> verify_task( | 423 std::unique_ptr<Task> verify_task( |
402 new Task(FROM_HERE, Bind(&VerifyNoTaskRunnerHandle), | 424 new Task(FROM_HERE, Bind(&VerifyNoTaskRunnerHandle), |
403 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 425 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
404 | 426 |
405 RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); | 427 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
406 } | 428 } |
407 | 429 |
408 static void VerifySequencedTaskRunnerHandle( | 430 static void VerifySequencedTaskRunnerHandle( |
409 const SequencedTaskRunner* expected_task_runner) { | 431 const SequencedTaskRunner* expected_task_runner) { |
410 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); | 432 EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet()); |
411 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 433 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
412 EXPECT_EQ(expected_task_runner, SequencedTaskRunnerHandle::Get()); | 434 EXPECT_EQ(expected_task_runner, SequencedTaskRunnerHandle::Get()); |
413 } | 435 } |
414 | 436 |
415 TEST_P(TaskSchedulerTaskTrackerTest, | 437 TEST_P(TaskSchedulerTaskTrackerTest, |
416 SequencedTaskRunnerHandleIsSetOnSequenced) { | 438 SequencedTaskRunnerHandleIsSetOnSequenced) { |
417 scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner); | 439 scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner); |
418 | 440 |
419 // Create a task that will verify that SequencedTaskRunnerHandle is properly | 441 // Create a task that will verify that SequencedTaskRunnerHandle is properly |
420 // set to |test_task_runner| in its scope per |sequenced_task_runner_ref| | 442 // set to |test_task_runner| in its scope per |sequenced_task_runner_ref| |
421 // being set to it. | 443 // being set to it. |
422 std::unique_ptr<Task> verify_task( | 444 std::unique_ptr<Task> verify_task( |
423 new Task(FROM_HERE, Bind(&VerifySequencedTaskRunnerHandle, | 445 new Task(FROM_HERE, Bind(&VerifySequencedTaskRunnerHandle, |
424 base::Unretained(test_task_runner.get())), | 446 base::Unretained(test_task_runner.get())), |
425 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 447 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
426 verify_task->sequenced_task_runner_ref = test_task_runner; | 448 verify_task->sequenced_task_runner_ref = test_task_runner; |
427 | 449 |
428 RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); | 450 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
429 } | 451 } |
430 | 452 |
431 static void VerifyThreadTaskRunnerHandle( | 453 static void VerifyThreadTaskRunnerHandle( |
432 const SingleThreadTaskRunner* expected_task_runner) { | 454 const SingleThreadTaskRunner* expected_task_runner) { |
433 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); | 455 EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet()); |
434 // SequencedTaskRunnerHandle inherits ThreadTaskRunnerHandle for thread. | 456 // SequencedTaskRunnerHandle inherits ThreadTaskRunnerHandle for thread. |
435 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); | 457 EXPECT_TRUE(SequencedTaskRunnerHandle::IsSet()); |
436 EXPECT_EQ(expected_task_runner, ThreadTaskRunnerHandle::Get()); | 458 EXPECT_EQ(expected_task_runner, ThreadTaskRunnerHandle::Get()); |
437 } | 459 } |
438 | 460 |
439 TEST_P(TaskSchedulerTaskTrackerTest, | 461 TEST_P(TaskSchedulerTaskTrackerTest, |
440 ThreadTaskRunnerHandleIsSetOnSingleThreaded) { | 462 ThreadTaskRunnerHandleIsSetOnSingleThreaded) { |
441 scoped_refptr<SingleThreadTaskRunner> test_task_runner( | 463 scoped_refptr<SingleThreadTaskRunner> test_task_runner( |
442 new TestSimpleTaskRunner); | 464 new TestSimpleTaskRunner); |
443 | 465 |
444 // Create a task that will verify that ThreadTaskRunnerHandle is properly set | 466 // Create a task that will verify that ThreadTaskRunnerHandle is properly set |
445 // to |test_task_runner| in its scope per |single_thread_task_runner_ref| | 467 // to |test_task_runner| in its scope per |single_thread_task_runner_ref| |
446 // being set on it. | 468 // being set on it. |
447 std::unique_ptr<Task> verify_task( | 469 std::unique_ptr<Task> verify_task( |
448 new Task(FROM_HERE, Bind(&VerifyThreadTaskRunnerHandle, | 470 new Task(FROM_HERE, Bind(&VerifyThreadTaskRunnerHandle, |
449 base::Unretained(test_task_runner.get())), | 471 base::Unretained(test_task_runner.get())), |
450 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); | 472 TaskTraits().WithShutdownBehavior(GetParam()), TimeDelta())); |
451 verify_task->single_thread_task_runner_ref = test_task_runner; | 473 verify_task->single_thread_task_runner_ref = test_task_runner; |
452 | 474 |
453 RunTaskRunnerHandleVerificationTask(&tracker_, verify_task.get()); | 475 RunTaskRunnerHandleVerificationTask(&tracker_, std::move(verify_task)); |
454 } | 476 } |
455 | 477 |
456 INSTANTIATE_TEST_CASE_P( | 478 INSTANTIATE_TEST_CASE_P( |
457 ContinueOnShutdown, | 479 ContinueOnShutdown, |
458 TaskSchedulerTaskTrackerTest, | 480 TaskSchedulerTaskTrackerTest, |
459 ::testing::Values(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 481 ::testing::Values(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); |
460 INSTANTIATE_TEST_CASE_P( | 482 INSTANTIATE_TEST_CASE_P( |
461 SkipOnShutdown, | 483 SkipOnShutdown, |
462 TaskSchedulerTaskTrackerTest, | 484 TaskSchedulerTaskTrackerTest, |
463 ::testing::Values(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 485 ::testing::Values(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); |
464 INSTANTIATE_TEST_CASE_P( | 486 INSTANTIATE_TEST_CASE_P( |
465 BlockShutdown, | 487 BlockShutdown, |
466 TaskSchedulerTaskTrackerTest, | 488 TaskSchedulerTaskTrackerTest, |
467 ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 489 ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
468 | 490 |
491 namespace { | |
robliao
2016/07/25 17:57:21
Nit: Padding one line break after "namespace {" an
fdoray
2016/07/26 20:44:56
Done.
| |
492 void ExpectSequenceToken(SequenceToken sequence_token) { | |
493 EXPECT_EQ(sequence_token, SequenceToken::GetCurrent()); | |
494 } | |
495 } // namespace | |
496 | |
497 // Verify that SequenceToken::GetCurrent() returns the Sequence's token when a | |
498 // Task runs. | |
499 TEST_F(TaskSchedulerTaskTrackerTest, CurrentSequenceToken) { | |
500 scoped_refptr<Sequence> sequence(new Sequence); | |
501 sequence->PushTask(WrapUnique( | |
502 new Task(FROM_HERE, Bind(&ExpectSequenceToken, sequence->token()), | |
503 TaskTraits(), TimeDelta()))); | |
504 tracker_.WillPostTask(sequence->PeekTask()); | |
505 | |
506 EXPECT_FALSE(SequenceToken::GetCurrent().IsValid()); | |
507 tracker_.RunNextTaskInSequence(sequence.get()); | |
508 EXPECT_FALSE(SequenceToken::GetCurrent().IsValid()); | |
509 } | |
510 | |
469 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { | 511 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) { |
470 // Post and run tasks asynchronously. | 512 // Post and run tasks asynchronously. |
471 std::vector<std::unique_ptr<Task>> tasks; | |
472 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 513 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
473 | 514 |
474 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 515 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
475 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
476 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 516 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
477 &tracker_, tasks.back().get(), | 517 &tracker_, CreateSequenceWithTask( |
518 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), | |
478 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 519 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
479 threads.back()->Start(); | 520 threads.back()->Start(); |
480 | 521 |
481 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
482 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 522 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
483 &tracker_, tasks.back().get(), | 523 &tracker_, CreateSequenceWithTask( |
524 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), | |
484 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 525 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
485 threads.back()->Start(); | 526 threads.back()->Start(); |
486 | 527 |
487 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
488 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 528 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
489 &tracker_, tasks.back().get(), | 529 &tracker_, CreateSequenceWithTask( |
530 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), | |
490 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 531 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
491 threads.back()->Start(); | 532 threads.back()->Start(); |
492 } | 533 } |
493 | 534 |
494 for (const auto& thread : threads) | 535 for (const auto& thread : threads) |
495 thread->Join(); | 536 thread->Join(); |
496 | 537 |
497 // Expect all tasks to be executed. | 538 // Expect all tasks to be executed. |
498 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); | 539 EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted()); |
499 | 540 |
500 // Should return immediately because no tasks are blocking shutdown. | 541 // Should return immediately because no tasks are blocking shutdown. |
501 tracker_.Shutdown(); | 542 tracker_.Shutdown(); |
502 } | 543 } |
503 | 544 |
504 TEST_F(TaskSchedulerTaskTrackerTest, | 545 TEST_F(TaskSchedulerTaskTrackerTest, |
505 LoadWillPostBeforeShutdownAndRunDuringShutdown) { | 546 LoadWillPostBeforeShutdownAndRunDuringShutdown) { |
506 // Post tasks asynchronously. | 547 // Post tasks asynchronously. |
507 std::vector<std::unique_ptr<Task>> tasks; | 548 std::vector<scoped_refptr<Sequence>> sequences; |
508 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; | 549 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads; |
509 | 550 |
510 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 551 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
511 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | 552 sequences.push_back(CreateSequenceWithTask( |
553 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN))); | |
512 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 554 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
513 &tracker_, tasks.back().get(), | 555 &tracker_, sequences.back(), |
514 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 556 ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
515 post_threads.back()->Start(); | 557 post_threads.back()->Start(); |
516 | 558 |
517 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | 559 sequences.push_back(CreateSequenceWithTask( |
560 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN))); | |
518 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 561 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
519 &tracker_, tasks.back().get(), | 562 &tracker_, sequences.back(), |
520 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 563 ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
521 post_threads.back()->Start(); | 564 post_threads.back()->Start(); |
522 | 565 |
523 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 566 sequences.push_back(CreateSequenceWithTask( |
567 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN))); | |
524 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 568 post_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
525 &tracker_, tasks.back().get(), | 569 &tracker_, sequences.back(), |
526 ThreadPostingAndRunningTask::Action::WILL_POST, true))); | 570 ThreadPostingAndRunningTask::Action::WILL_POST, true))); |
527 post_threads.back()->Start(); | 571 post_threads.back()->Start(); |
528 } | 572 } |
529 | 573 |
530 for (const auto& thread : post_threads) | 574 for (const auto& thread : post_threads) |
531 thread->Join(); | 575 thread->Join(); |
532 | 576 |
533 // Call Shutdown() asynchronously. | 577 // Call Shutdown() asynchronously. |
534 CallShutdownAsync(); | 578 CallShutdownAsync(); |
535 | 579 |
536 // Run tasks asynchronously. | 580 // Run tasks asynchronously. |
537 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; | 581 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads; |
538 | 582 |
539 for (const auto& task : tasks) { | 583 for (const auto& sequence : sequences) { |
540 run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 584 run_threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
541 &tracker_, task.get(), ThreadPostingAndRunningTask::Action::RUN, | 585 &tracker_, sequence, ThreadPostingAndRunningTask::Action::RUN, false))); |
542 false))); | |
543 run_threads.back()->Start(); | 586 run_threads.back()->Start(); |
544 } | 587 } |
545 | 588 |
546 for (const auto& thread : run_threads) | 589 for (const auto& thread : run_threads) |
547 thread->Join(); | 590 thread->Join(); |
548 | 591 |
549 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 592 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
550 | 593 |
551 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 594 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
552 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 595 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
553 } | 596 } |
554 | 597 |
555 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { | 598 TEST_F(TaskSchedulerTaskTrackerTest, LoadWillPostAndRunDuringShutdown) { |
556 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to | 599 // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to |
557 // block shutdown. | 600 // block shutdown. |
558 std::unique_ptr<Task> block_shutdown_task( | 601 std::unique_ptr<Task> block_shutdown_task( |
559 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | 602 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); |
560 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); | 603 EXPECT_TRUE(tracker_.WillPostTask(block_shutdown_task.get())); |
561 | 604 |
562 // Call Shutdown() asynchronously. | 605 // Call Shutdown() asynchronously. |
563 CallShutdownAsync(); | 606 CallShutdownAsync(); |
564 | 607 |
565 // Post and run tasks asynchronously. | 608 // Post and run tasks asynchronously. |
566 std::vector<std::unique_ptr<Task>> tasks; | |
567 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; | 609 std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads; |
568 | 610 |
569 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { | 611 for (size_t i = 0; i < kLoadTestNumIterations; ++i) { |
570 tasks.push_back(CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)); | |
571 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 612 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
572 &tracker_, tasks.back().get(), | 613 &tracker_, CreateSequenceWithTask( |
614 CreateTask(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)), | |
573 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 615 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
574 threads.back()->Start(); | 616 threads.back()->Start(); |
575 | 617 |
576 tasks.push_back(CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)); | |
577 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 618 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
578 &tracker_, tasks.back().get(), | 619 &tracker_, CreateSequenceWithTask( |
620 CreateTask(TaskShutdownBehavior::SKIP_ON_SHUTDOWN)), | |
579 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); | 621 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false))); |
580 threads.back()->Start(); | 622 threads.back()->Start(); |
581 | 623 |
582 tasks.push_back(CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)); | |
583 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( | 624 threads.push_back(WrapUnique(new ThreadPostingAndRunningTask( |
584 &tracker_, tasks.back().get(), | 625 &tracker_, CreateSequenceWithTask( |
626 CreateTask(TaskShutdownBehavior::BLOCK_SHUTDOWN)), | |
585 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); | 627 ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true))); |
586 threads.back()->Start(); | 628 threads.back()->Start(); |
587 } | 629 } |
588 | 630 |
589 for (const auto& thread : threads) | 631 for (const auto& thread : threads) |
590 thread->Join(); | 632 thread->Join(); |
591 | 633 |
592 // Expect BLOCK_SHUTDOWN tasks to have been executed. | 634 // Expect BLOCK_SHUTDOWN tasks to have been executed. |
593 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); | 635 EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted()); |
594 | 636 |
595 // Shutdown() shouldn't return before |block_shutdown_task| is executed. | 637 // Shutdown() shouldn't return before |block_shutdown_task| is executed. |
596 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); | 638 VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS(); |
597 | 639 |
598 // Unblock shutdown by running |block_shutdown_task|. | 640 // Unblock shutdown by running |block_shutdown_task|. |
599 tracker_.RunTask(block_shutdown_task.get()); | 641 tracker_.RunNextTaskInSequence( |
642 CreateSequenceWithTask(std::move(block_shutdown_task)).get()); | |
600 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); | 643 EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted()); |
601 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); | 644 WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED(); |
602 } | 645 } |
603 | 646 |
604 } // namespace internal | 647 } // namespace internal |
605 } // namespace base | 648 } // namespace base |
OLD | NEW |