• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/task/thread_pool/task_tracker.h"
6 
7 #include <stdint.h>
8 
9 #include <memory>
10 #include <utility>
11 #include <vector>
12 
13 #include "base/barrier_closure.h"
14 #include "base/check_op.h"
15 #include "base/functional/bind.h"
16 #include "base/functional/callback.h"
17 #include "base/functional/callback_helpers.h"
18 #include "base/memory/ptr_util.h"
19 #include "base/memory/raw_ptr.h"
20 #include "base/memory/ref_counted.h"
21 #include "base/metrics/histogram_base.h"
22 #include "base/metrics/histogram_samples.h"
23 #include "base/sequence_token.h"
24 #include "base/synchronization/atomic_flag.h"
25 #include "base/task/common/checked_lock.h"
26 #include "base/task/sequenced_task_runner.h"
27 #include "base/task/single_thread_task_runner.h"
28 #include "base/task/task_traits.h"
29 #include "base/task/thread_pool/task.h"
30 #include "base/task/thread_pool/test_utils.h"
31 #include "base/test/bind.h"
32 #include "base/test/gtest_util.h"
33 #include "base/test/metrics/histogram_tester.h"
34 #include "base/test/test_simple_task_runner.h"
35 #include "base/test/test_timeouts.h"
36 #include "base/test/test_waitable_event.h"
37 #include "base/threading/platform_thread.h"
38 #include "base/threading/scoped_blocking_call.h"
39 #include "base/threading/simple_thread.h"
40 #include "base/threading/thread_restrictions.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43 
44 namespace base {
45 namespace internal {
46 
47 namespace {
48 
49 constexpr size_t kLoadTestNumIterations = 75;
50 
51 // Invokes a closure asynchronously.
52 class CallbackThread : public SimpleThread {
53  public:
CallbackThread(OnceClosure closure)54   explicit CallbackThread(OnceClosure closure)
55       : SimpleThread("CallbackThread"), closure_(std::move(closure)) {}
56   CallbackThread(const CallbackThread&) = delete;
57   CallbackThread& operator=(const CallbackThread&) = delete;
58 
59   // Returns true once the callback returns.
has_returned()60   bool has_returned() { return has_returned_.IsSet(); }
61 
62  private:
Run()63   void Run() override {
64     std::move(closure_).Run();
65     has_returned_.Set();
66   }
67 
68   OnceClosure closure_;
69   AtomicFlag has_returned_;
70 };
71 
72 class ThreadPostingAndRunningTask : public SimpleThread {
73  public:
74   enum class Action {
75     WILL_POST,
76     RUN,
77     WILL_POST_AND_RUN,
78   };
79 
80   // |action| must be either WILL_POST of WILL_POST_AND_RUN.
81   // |task| will be pushed to |sequence| and |sequence| will be registered. If
82   // |action| is WILL_POST_AND_RUN, a task from |sequence| will run.
ThreadPostingAndRunningTask(TaskTracker * tracker,scoped_refptr<Sequence> sequence,Action action,bool expect_post_succeeds,Task task)83   ThreadPostingAndRunningTask(TaskTracker* tracker,
84                               scoped_refptr<Sequence> sequence,
85                               Action action,
86                               bool expect_post_succeeds,
87                               Task task)
88       : SimpleThread("ThreadPostingAndRunningTask"),
89         tracker_(tracker),
90         task_(std::move(task)),
91         sequence_(std::move(sequence)),
92         action_(action),
93         expect_post_succeeds_(expect_post_succeeds) {
94     EXPECT_TRUE(task_.task);
95     EXPECT_TRUE(sequence_);
96     EXPECT_NE(Action::RUN, action_);
97   }
98 
99   // A task from |task_source| will run.
ThreadPostingAndRunningTask(TaskTracker * tracker,RegisteredTaskSource task_source)100   ThreadPostingAndRunningTask(TaskTracker* tracker,
101                               RegisteredTaskSource task_source)
102       : SimpleThread("ThreadPostingAndRunningTask"),
103         tracker_(tracker),
104         task_source_(std::move(task_source)),
105         action_(Action::RUN),
106         expect_post_succeeds_(false) {
107     EXPECT_TRUE(task_source_);
108   }
109   ThreadPostingAndRunningTask(const ThreadPostingAndRunningTask&) = delete;
110   ThreadPostingAndRunningTask& operator=(const ThreadPostingAndRunningTask&) =
111       delete;
112 
TakeTaskSource()113   RegisteredTaskSource TakeTaskSource() { return std::move(task_source_); }
114 
115  private:
Run()116   void Run() override {
117     bool post_and_queue_succeeded = true;
118     if (action_ == Action::WILL_POST || action_ == Action::WILL_POST_AND_RUN) {
119       EXPECT_TRUE(task_.task);
120 
121       post_and_queue_succeeded =
122           tracker_->WillPostTask(&task_, sequence_->shutdown_behavior());
123       {
124         auto transaction = sequence_->BeginTransaction();
125         transaction.WillPushImmediateTask();
126         transaction.PushImmediateTask(std::move(task_));
127       }
128       task_source_ = tracker_->RegisterTaskSource(std::move(sequence_));
129 
130       post_and_queue_succeeded &= !!task_source_;
131 
132       EXPECT_EQ(expect_post_succeeds_, post_and_queue_succeeded);
133     }
134     if (post_and_queue_succeeded &&
135         (action_ == Action::RUN || action_ == Action::WILL_POST_AND_RUN)) {
136       EXPECT_TRUE(task_source_);
137       task_source_.WillRunTask();
138 
139       // Expect RunAndPopNextTask to return nullptr since |sequence| is empty
140       // after popping a task from it.
141       EXPECT_FALSE(tracker_->RunAndPopNextTask(std::move(task_source_)));
142     }
143   }
144 
145   const raw_ptr<TaskTracker> tracker_;
146   Task task_;
147   scoped_refptr<Sequence> sequence_;
148   RegisteredTaskSource task_source_;
149   const Action action_;
150   const bool expect_post_succeeds_;
151 };
152 
153 class ThreadPoolTaskTrackerTest
154     : public testing::TestWithParam<TaskShutdownBehavior> {
155  public:
156   ThreadPoolTaskTrackerTest(const ThreadPoolTaskTrackerTest&) = delete;
157   ThreadPoolTaskTrackerTest& operator=(const ThreadPoolTaskTrackerTest&) =
158       delete;
159 
160  protected:
161   ThreadPoolTaskTrackerTest() = default;
162 
163   // Creates a task.
CreateTask()164   Task CreateTask() {
165     return Task(
166         FROM_HERE,
167         BindOnce(&ThreadPoolTaskTrackerTest::RunTaskCallback, Unretained(this)),
168         TimeTicks::Now(), TimeDelta());
169   }
170 
WillPostTaskAndQueueTaskSource(Task task,const TaskTraits & traits)171   RegisteredTaskSource WillPostTaskAndQueueTaskSource(
172       Task task,
173       const TaskTraits& traits) {
174     if (!tracker_.WillPostTask(&task, traits.shutdown_behavior()))
175       return nullptr;
176     auto sequence = test::CreateSequenceWithTask(std::move(task), traits);
177     return tracker_.RegisterTaskSource(std::move(sequence));
178   }
RunAndPopNextTask(RegisteredTaskSource task_source)179   RegisteredTaskSource RunAndPopNextTask(RegisteredTaskSource task_source) {
180     task_source.WillRunTask();
181     return tracker_.RunAndPopNextTask(std::move(task_source));
182   }
183 
184   // Calls tracker_->CompleteShutdown() on a new thread and expects it to block.
ExpectAsyncCompleteShutdownBlocks()185   void ExpectAsyncCompleteShutdownBlocks() {
186     ASSERT_FALSE(thread_calling_shutdown_);
187     ASSERT_TRUE(tracker_.HasShutdownStarted());
188     thread_calling_shutdown_ = std::make_unique<CallbackThread>(
189         BindOnce(&TaskTracker::CompleteShutdown, Unretained(&tracker_)));
190     thread_calling_shutdown_->Start();
191     PlatformThread::Sleep(TestTimeouts::tiny_timeout());
192     VerifyAsyncShutdownInProgress();
193   }
194 
WaitForAsyncIsShutdownComplete()195   void WaitForAsyncIsShutdownComplete() {
196     ASSERT_TRUE(thread_calling_shutdown_);
197     thread_calling_shutdown_->Join();
198     EXPECT_TRUE(thread_calling_shutdown_->has_returned());
199     EXPECT_TRUE(tracker_.IsShutdownComplete());
200   }
201 
VerifyAsyncShutdownInProgress()202   void VerifyAsyncShutdownInProgress() {
203     ASSERT_TRUE(thread_calling_shutdown_);
204     EXPECT_FALSE(thread_calling_shutdown_->has_returned());
205     EXPECT_TRUE(tracker_.HasShutdownStarted());
206     EXPECT_FALSE(tracker_.IsShutdownComplete());
207   }
208 
209   // Calls tracker_->FlushForTesting() on a new thread.
CallFlushFromAnotherThread()210   void CallFlushFromAnotherThread() {
211     threads_calling_flush_.push_back(std::make_unique<CallbackThread>(
212         BindOnce(&TaskTracker::FlushForTesting, Unretained(&tracker_))));
213     threads_calling_flush_.back()->Start();
214   }
215 
WaitForAsyncFlushesReturned()216   void WaitForAsyncFlushesReturned() {
217     ASSERT_GE(threads_calling_flush_.size(), 1U);
218     for (auto& thread_calling_flush : threads_calling_flush_) {
219       thread_calling_flush->Join();
220       EXPECT_TRUE(thread_calling_flush->has_returned());
221     }
222   }
223 
VerifyAsyncFlushesInProgress()224   void VerifyAsyncFlushesInProgress() {
225     ASSERT_GE(threads_calling_flush_.size(), 1U);
226     for (auto& thread_calling_flush : threads_calling_flush_) {
227       EXPECT_FALSE(thread_calling_flush->has_returned());
228     }
229   }
230 
NumTasksExecuted()231   size_t NumTasksExecuted() {
232     CheckedAutoLock auto_lock(lock_);
233     return num_tasks_executed_;
234   }
235 
236   TaskTracker tracker_;
237 
238  private:
RunTaskCallback()239   void RunTaskCallback() {
240     CheckedAutoLock auto_lock(lock_);
241     ++num_tasks_executed_;
242   }
243 
244   std::unique_ptr<CallbackThread> thread_calling_shutdown_;
245   std::vector<std::unique_ptr<CallbackThread>> threads_calling_flush_;
246 
247   // Synchronizes accesses to |num_tasks_executed_|.
248   CheckedLock lock_;
249 
250   size_t num_tasks_executed_ = 0;
251 };
252 
253 #define WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED() \
254   do {                                      \
255     SCOPED_TRACE("");                       \
256     WaitForAsyncIsShutdownComplete();       \
257   } while (false)
258 
259 #define VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS() \
260   do {                                      \
261     SCOPED_TRACE("");                       \
262     VerifyAsyncShutdownInProgress();        \
263   } while (false)
264 
265 #define WAIT_FOR_ASYNC_FLUSHES_RETURNED() \
266   do {                                    \
267     SCOPED_TRACE("");                     \
268     WaitForAsyncFlushesReturned();        \
269   } while (false)
270 
271 #define VERIFY_ASYNC_FLUSHES_IN_PROGRESS() \
272   do {                                     \
273     SCOPED_TRACE("");                      \
274     VerifyAsyncFlushesInProgress();        \
275   } while (false)
276 
277 }  // namespace
278 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAndRunBeforeShutdown)279 TEST_P(ThreadPoolTaskTrackerTest, WillPostAndRunBeforeShutdown) {
280   Task task(CreateTask());
281 
282   // Inform |task_tracker_| that |task| will be posted.
283   EXPECT_TRUE(tracker_.WillPostTask(&task, GetParam()));
284 
285   // Run the task.
286   EXPECT_EQ(0U, NumTasksExecuted());
287 
288   test::QueueAndRunTaskSource(
289       &tracker_, test::CreateSequenceWithTask(std::move(task), {GetParam()}));
290   EXPECT_EQ(1U, NumTasksExecuted());
291 
292   // Shutdown() shouldn't block.
293   test::ShutdownTaskTracker(&tracker_);
294 }
295 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAndRunLongTaskBeforeShutdown)296 TEST_P(ThreadPoolTaskTrackerTest, WillPostAndRunLongTaskBeforeShutdown) {
297   // Create a task that signals |task_running| and blocks until |task_barrier|
298   // is signaled.
299   TestWaitableEvent task_running;
300   TestWaitableEvent task_barrier;
301   Task blocked_task(FROM_HERE, BindLambdaForTesting([&]() {
302                       task_running.Signal();
303                       task_barrier.Wait();
304                     }),
305                     TimeTicks::Now(), TimeDelta());
306 
307   // Inform |task_tracker_| that |blocked_task| will be posted.
308   auto sequence =
309       WillPostTaskAndQueueTaskSource(std::move(blocked_task), {GetParam()});
310   EXPECT_TRUE(sequence);
311 
312   // Create a thread to run the task. Wait until the task starts running.
313   ThreadPostingAndRunningTask thread_running_task(&tracker_,
314                                                   std::move(sequence));
315   thread_running_task.Start();
316   task_running.Wait();
317 
318   // Initiate shutdown after the task has started to run.
319   tracker_.StartShutdown();
320 
321   if (GetParam() == TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN) {
322     // Shutdown should complete even with a CONTINUE_ON_SHUTDOWN in progress.
323     tracker_.CompleteShutdown();
324   } else {
325     // Shutdown should block with any non CONTINUE_ON_SHUTDOWN task in progress.
326     ExpectAsyncCompleteShutdownBlocks();
327   }
328 
329   // Unblock the task.
330   task_barrier.Signal();
331   thread_running_task.Join();
332 
333   // Shutdown should now complete for a non CONTINUE_ON_SHUTDOWN task.
334   if (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN)
335     WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
336 }
337 
338 // Verify that an undelayed task whose sequence wasn't queued does not block
339 // shutdown, regardless of its shutdown behavior.
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownQueueDuringShutdown)340 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownQueueDuringShutdown) {
341   // Simulate posting a undelayed task.
342   Task task{CreateTask()};
343   EXPECT_TRUE(tracker_.WillPostTask(&task, GetParam()));
344   auto sequence = test::CreateSequenceWithTask(std::move(task), {GetParam()});
345 
346   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
347   // block shutdown.
348   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
349       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
350   EXPECT_TRUE(block_shutdown_sequence);
351 
352   // Start shutdown and try to complete it asynchronously.
353   tracker_.StartShutdown();
354   ExpectAsyncCompleteShutdownBlocks();
355 
356   const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN;
357   if (should_run) {
358     test::QueueAndRunTaskSource(&tracker_, std::move(sequence));
359     EXPECT_EQ(1U, NumTasksExecuted());
360     VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
361   } else {
362     EXPECT_FALSE(tracker_.RegisterTaskSource(std::move(sequence)));
363   }
364 
365   // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task.
366   RunAndPopNextTask(std::move(block_shutdown_sequence));
367   EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted());
368   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
369 }
370 
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownRunDuringShutdown)371 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownRunDuringShutdown) {
372   // Inform |task_tracker_| that a task will be posted.
373   auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
374   EXPECT_TRUE(sequence);
375 
376   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
377   // block shutdown.
378   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
379       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
380   EXPECT_TRUE(block_shutdown_sequence);
381 
382   // Start shutdown and try to complete it asynchronously.
383   tracker_.StartShutdown();
384   ExpectAsyncCompleteShutdownBlocks();
385 
386   // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it
387   // should be discarded.
388   EXPECT_EQ(0U, NumTasksExecuted());
389   const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN;
390 
391   RunAndPopNextTask(std::move(sequence));
392   EXPECT_EQ(should_run ? 1U : 0U, NumTasksExecuted());
393   VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
394 
395   // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task.
396   RunAndPopNextTask(std::move(block_shutdown_sequence));
397   EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted());
398   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
399 }
400 
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownRunAfterShutdown)401 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) {
402   // Inform |task_tracker_| that a task will be posted.
403   auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
404   EXPECT_TRUE(sequence);
405 
406   // Start shutdown.
407   tracker_.StartShutdown();
408   EXPECT_EQ(0U, NumTasksExecuted());
409 
410   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
411     // Verify that CompleteShutdown() blocks.
412     ExpectAsyncCompleteShutdownBlocks();
413 
414     // Run the task to unblock shutdown.
415     RunAndPopNextTask(std::move(sequence));
416     EXPECT_EQ(1U, NumTasksExecuted());
417     WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
418 
419     // It is not possible to test running a BLOCK_SHUTDOWN task posted before
420     // shutdown after shutdown because Shutdown() won't return if there are
421     // pending BLOCK_SHUTDOWN tasks.
422   } else {
423     tracker_.CompleteShutdown();
424 
425     // The task shouldn't be allowed to run after shutdown.
426     RunAndPopNextTask(std::move(sequence));
427     EXPECT_EQ(0U, NumTasksExecuted());
428   }
429 }
430 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAndRunDuringShutdown)431 TEST_P(ThreadPoolTaskTrackerTest, WillPostAndRunDuringShutdown) {
432   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
433   // block shutdown.
434   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
435       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
436   EXPECT_TRUE(block_shutdown_sequence);
437 
438   // Start shutdown.
439   tracker_.StartShutdown();
440 
441   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
442     // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted.
443     auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
444     EXPECT_TRUE(sequence);
445 
446     // Run the BLOCK_SHUTDOWN task.
447     EXPECT_EQ(0U, NumTasksExecuted());
448     RunAndPopNextTask(std::move(sequence));
449     EXPECT_EQ(1U, NumTasksExecuted());
450   } else {
451     // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task.
452     auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
453     EXPECT_FALSE(sequence);
454 
455     // Don't try to run the task, because it wasn't allowed to be posted.
456   }
457 
458   // Verify that CompleteShutdown() blocks.
459   ExpectAsyncCompleteShutdownBlocks();
460 
461   // Unblock shutdown by running |block_shutdown_task|.
462   RunAndPopNextTask(std::move(block_shutdown_sequence));
463   EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U,
464             NumTasksExecuted());
465   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
466 }
467 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAfterShutdown)468 TEST_P(ThreadPoolTaskTrackerTest, WillPostAfterShutdown) {
469   test::ShutdownTaskTracker(&tracker_);
470 
471   Task task(CreateTask());
472 
473   // |task_tracker_| shouldn't allow a task to be posted after shutdown.
474   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
475     // When the task tracker is allowed to fizzle block shutdown tasks,
476     // WillPostTask will return false and leak the task.
477     tracker_.BeginFizzlingBlockShutdownTasks();
478     EXPECT_FALSE(tracker_.WillPostTask(&task, GetParam()));
479     tracker_.EndFizzlingBlockShutdownTasks();
480 
481     // If a BLOCK_SHUTDOWN task is posted after shutdown without explicitly
482     // allowing BLOCK_SHUTDOWN task fizzling, WillPostTask DCHECKs to find
483     // ordering bugs.
484     EXPECT_DCHECK_DEATH(tracker_.WillPostTask(&task, GetParam()));
485   } else {
486     EXPECT_FALSE(tracker_.WillPostTask(&task, GetParam()));
487   }
488 }
489 
490 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can
491 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't.
TEST_P(ThreadPoolTaskTrackerTest,SingletonAllowed)492 TEST_P(ThreadPoolTaskTrackerTest, SingletonAllowed) {
493   const bool can_use_singletons =
494       (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
495 
496   Task task(FROM_HERE, BindOnce(&internal::AssertSingletonAllowed),
497             TimeTicks::Now(), TimeDelta());
498   auto sequence = WillPostTaskAndQueueTaskSource(std::move(task), {GetParam()});
499   EXPECT_TRUE(sequence);
500 
501   // Running the task should fail iff the task isn't allowed to use singletons.
502   if (can_use_singletons) {
503     EXPECT_FALSE(RunAndPopNextTask(std::move(sequence)));
504   } else {
505     EXPECT_DCHECK_DEATH({ RunAndPopNextTask(std::move(sequence)); });
506   }
507 }
508 
509 // Verify that AssertIOAllowed() succeeds only for a MayBlock() task.
TEST_P(ThreadPoolTaskTrackerTest,IOAllowed)510 TEST_P(ThreadPoolTaskTrackerTest, IOAllowed) {
511   // Allowed with MayBlock().
512   Task task_with_may_block(FROM_HERE, BindOnce([]() {
513                              // Shouldn't fail.
514                              ScopedBlockingCall scope_blocking_call(
515                                  FROM_HERE, BlockingType::WILL_BLOCK);
516                            }),
517                            TimeTicks::Now(), TimeDelta());
518   TaskTraits traits_with_may_block{MayBlock(), GetParam()};
519   auto sequence_with_may_block = WillPostTaskAndQueueTaskSource(
520       std::move(task_with_may_block), traits_with_may_block);
521   EXPECT_TRUE(sequence_with_may_block);
522   RunAndPopNextTask(std::move(sequence_with_may_block));
523 
524   // Disallowed in the absence of MayBlock().
525   Task task_without_may_block(FROM_HERE, BindOnce([]() {
526                                 EXPECT_DCHECK_DEATH({
527                                   ScopedBlockingCall scope_blocking_call(
528                                       FROM_HERE, BlockingType::WILL_BLOCK);
529                                 });
530                               }),
531                               TimeTicks::Now(), TimeDelta());
532   TaskTraits traits_without_may_block = TaskTraits(GetParam());
533   auto sequence_without_may_block = WillPostTaskAndQueueTaskSource(
534       std::move(task_without_may_block), traits_without_may_block);
535   EXPECT_TRUE(sequence_without_may_block);
536   RunAndPopNextTask(std::move(sequence_without_may_block));
537 }
538 
RunTaskRunnerCurrentDefaultHandleVerificationTask(TaskTracker * tracker,Task verify_task,TaskTraits traits,scoped_refptr<TaskRunner> task_runner,TaskSourceExecutionMode execution_mode)539 static void RunTaskRunnerCurrentDefaultHandleVerificationTask(
540     TaskTracker* tracker,
541     Task verify_task,
542     TaskTraits traits,
543     scoped_refptr<TaskRunner> task_runner,
544     TaskSourceExecutionMode execution_mode) {
545   // Pretend |verify_task| is posted to respect TaskTracker's contract.
546   EXPECT_TRUE(tracker->WillPostTask(&verify_task, traits.shutdown_behavior()));
547 
548   // Confirm that the test conditions are right (no
549   // task runner CurrentDefaultHandles set already).
550   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
551   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
552 
553   test::QueueAndRunTaskSource(
554       tracker,
555       test::CreateSequenceWithTask(std::move(verify_task), traits,
556                                    std::move(task_runner), execution_mode));
557 
558   // task runner CurrentDefaultHandle state is reset outside of task's scope.
559   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
560   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
561 }
562 
VerifyNoTaskRunnerCurrentDefaultHandle()563 static void VerifyNoTaskRunnerCurrentDefaultHandle() {
564   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
565   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
566 }
567 
TEST_P(ThreadPoolTaskTrackerTest,TaskRunnerHandleIsNotSetOnParallel)568 TEST_P(ThreadPoolTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) {
569   // Create a task that will verify that TaskRunnerHandles are not set in its
570   // scope per no TaskRunner ref being set to it.
571   Task verify_task(FROM_HERE, BindOnce(&VerifyNoTaskRunnerCurrentDefaultHandle),
572                    TimeTicks::Now(), TimeDelta());
573 
574   RunTaskRunnerCurrentDefaultHandleVerificationTask(
575       &tracker_, std::move(verify_task), TaskTraits(GetParam()), nullptr,
576       TaskSourceExecutionMode::kParallel);
577 }
578 
VerifySequencedTaskRunnerCurrentDefaultHandle(const SequencedTaskRunner * expected_task_runner)579 static void VerifySequencedTaskRunnerCurrentDefaultHandle(
580     const SequencedTaskRunner* expected_task_runner) {
581   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
582   EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
583   EXPECT_EQ(expected_task_runner, SequencedTaskRunner::GetCurrentDefault());
584 }
585 
TEST_P(ThreadPoolTaskTrackerTest,SequencedTaskRunnerHasCurrentDefaultOnSequenced)586 TEST_P(ThreadPoolTaskTrackerTest,
587        SequencedTaskRunnerHasCurrentDefaultOnSequenced) {
588   scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner);
589 
590   // Create a task that will verify that
591   // SequencedTaskRunner::CurrentDefaultHandle is properly set to
592   // |test_task_runner| in its scope per |sequenced_task_runner_ref| being set
593   // to it.
594   Task verify_task(FROM_HERE,
595                    BindOnce(&VerifySequencedTaskRunnerCurrentDefaultHandle,
596                             Unretained(test_task_runner.get())),
597                    TimeTicks::Now(), TimeDelta());
598 
599   RunTaskRunnerCurrentDefaultHandleVerificationTask(
600       &tracker_, std::move(verify_task), TaskTraits(GetParam()),
601       std::move(test_task_runner), TaskSourceExecutionMode::kSequenced);
602 }
603 
VerifySingleThreadTaskRunnerCurrentDefaultHandle(const SingleThreadTaskRunner * expected_task_runner)604 static void VerifySingleThreadTaskRunnerCurrentDefaultHandle(
605     const SingleThreadTaskRunner* expected_task_runner) {
606   EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
607   // SequencedTaskRunner::CurrentDefaultHandle inherits
608   // SingleThreadTaskRunner::CurrentDefaultHandle for thread.
609   EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
610   EXPECT_EQ(expected_task_runner, SingleThreadTaskRunner::GetCurrentDefault());
611 }
612 
TEST_P(ThreadPoolTaskTrackerTest,SingleThreadTaskRunnerCurrentDefaultHandleIsSetOnSingleThreaded)613 TEST_P(ThreadPoolTaskTrackerTest,
614        SingleThreadTaskRunnerCurrentDefaultHandleIsSetOnSingleThreaded) {
615   scoped_refptr<SingleThreadTaskRunner> test_task_runner(
616       new TestSimpleTaskRunner);
617 
618   // Create a task that will verify that
619   // SingleThreadTaskRunner::CurrentDefaultHandle is properly set to
620   // |test_task_runner| in its scope per |single_thread_task_runner_ref| being
621   // set on it.
622   Task verify_task(FROM_HERE,
623                    BindOnce(&VerifySingleThreadTaskRunnerCurrentDefaultHandle,
624                             Unretained(test_task_runner.get())),
625                    TimeTicks::Now(), TimeDelta());
626 
627   RunTaskRunnerCurrentDefaultHandleVerificationTask(
628       &tracker_, std::move(verify_task), TaskTraits(GetParam()),
629       std::move(test_task_runner), TaskSourceExecutionMode::kSingleThread);
630 }
631 
TEST_P(ThreadPoolTaskTrackerTest,FlushPendingDelayedTask)632 TEST_P(ThreadPoolTaskTrackerTest, FlushPendingDelayedTask) {
633   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
634   tracker_.WillPostTask(&delayed_task, GetParam());
635   // FlushForTesting() should return even if the delayed task didn't run.
636   tracker_.FlushForTesting();
637 }
638 
TEST_P(ThreadPoolTaskTrackerTest,FlushAsyncForTestingPendingDelayedTask)639 TEST_P(ThreadPoolTaskTrackerTest, FlushAsyncForTestingPendingDelayedTask) {
640   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
641   tracker_.WillPostTask(&delayed_task, GetParam());
642   // FlushAsyncForTesting() should callback even if the delayed task didn't run.
643   bool called_back = false;
644   tracker_.FlushAsyncForTesting(
645       BindOnce([](bool* called_back) { *called_back = true; },
646                Unretained(&called_back)));
647   EXPECT_TRUE(called_back);
648 }
649 
TEST_P(ThreadPoolTaskTrackerTest,FlushPendingUndelayedTask)650 TEST_P(ThreadPoolTaskTrackerTest, FlushPendingUndelayedTask) {
651   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
652   auto undelayed_sequence =
653       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
654 
655   // FlushForTesting() shouldn't return before the undelayed task runs.
656   CallFlushFromAnotherThread();
657   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
658   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
659 
660   // FlushForTesting() should return after the undelayed task runs.
661   RunAndPopNextTask(std::move(undelayed_sequence));
662   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
663 }
664 
TEST_P(ThreadPoolTaskTrackerTest,MultipleFlushes)665 TEST_P(ThreadPoolTaskTrackerTest, MultipleFlushes) {
666   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
667   auto undelayed_sequence =
668       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
669 
670   // Multiple flushes should all unwind after the task runs.
671   CallFlushFromAnotherThread();
672   CallFlushFromAnotherThread();
673   CallFlushFromAnotherThread();
674   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
675   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
676 
677   RunAndPopNextTask(std::move(undelayed_sequence));
678   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
679 }
680 
TEST_P(ThreadPoolTaskTrackerTest,FlushAsyncForTestingPendingUndelayedTask)681 TEST_P(ThreadPoolTaskTrackerTest, FlushAsyncForTestingPendingUndelayedTask) {
682   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
683   auto undelayed_sequence =
684       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
685 
686   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
687   TestWaitableEvent event;
688   tracker_.FlushAsyncForTesting(
689       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
690   EXPECT_FALSE(event.IsSignaled());
691 
692   // FlushAsyncForTesting() should callback after the undelayed task runs.
693   RunAndPopNextTask(std::move(undelayed_sequence));
694   event.Wait();
695 }
696 
TEST_P(ThreadPoolTaskTrackerTest,MultipleFlushAsyncForTesting)697 TEST_P(ThreadPoolTaskTrackerTest, MultipleFlushAsyncForTesting) {
698   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
699   auto undelayed_sequence =
700       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
701 
702   TestWaitableEvent three_callbacks_ran;
703   auto on_flush_done = BarrierClosure(
704       3,
705       BindOnce(&TestWaitableEvent::Signal, Unretained(&three_callbacks_ran)));
706   tracker_.FlushAsyncForTesting(on_flush_done);
707   tracker_.FlushAsyncForTesting(on_flush_done);
708   tracker_.FlushAsyncForTesting(on_flush_done);
709   EXPECT_FALSE(three_callbacks_ran.IsSignaled());
710 
711   // FlushAsyncForTesting() should callback after the undelayed task runs.
712   RunAndPopNextTask(std::move(undelayed_sequence));
713   three_callbacks_ran.Wait();
714 }
715 
TEST_P(ThreadPoolTaskTrackerTest,PostTaskDuringFlush)716 TEST_P(ThreadPoolTaskTrackerTest, PostTaskDuringFlush) {
717   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
718   auto undelayed_sequence =
719       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
720 
721   // FlushForTesting() shouldn't return before the undelayed task runs.
722   CallFlushFromAnotherThread();
723   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
724   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
725 
726   // Simulate posting another undelayed task.
727   Task other_undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(),
728                             TimeDelta());
729   auto other_undelayed_sequence = WillPostTaskAndQueueTaskSource(
730       std::move(other_undelayed_task), {GetParam()});
731 
732   // Run the first undelayed task.
733   RunAndPopNextTask(std::move(undelayed_sequence));
734 
735   // FlushForTesting() shouldn't return before the second undelayed task runs.
736   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
737   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
738 
739   // FlushForTesting() should return after the second undelayed task runs.
740   RunAndPopNextTask(std::move(other_undelayed_sequence));
741   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
742 }
743 
TEST_P(ThreadPoolTaskTrackerTest,PostTaskDuringFlushAsyncForTesting)744 TEST_P(ThreadPoolTaskTrackerTest, PostTaskDuringFlushAsyncForTesting) {
745   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
746   auto undelayed_sequence =
747       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
748 
749   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
750   TestWaitableEvent event;
751   tracker_.FlushAsyncForTesting(
752       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
753   EXPECT_FALSE(event.IsSignaled());
754 
755   // Simulate posting another undelayed task.
756   Task other_undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(),
757                             TimeDelta());
758   auto other_undelayed_sequence = WillPostTaskAndQueueTaskSource(
759       std::move(other_undelayed_task), {GetParam()});
760 
761   // Run the first undelayed task.
762   RunAndPopNextTask(std::move(undelayed_sequence));
763 
764   // FlushAsyncForTesting() shouldn't callback before the second undelayed task
765   // runs.
766   EXPECT_FALSE(event.IsSignaled());
767 
768   // FlushAsyncForTesting() should callback after the second undelayed task
769   // runs.
770   RunAndPopNextTask(std::move(other_undelayed_sequence));
771   event.Wait();
772 }
773 
TEST_P(ThreadPoolTaskTrackerTest,RunDelayedTaskDuringFlush)774 TEST_P(ThreadPoolTaskTrackerTest, RunDelayedTaskDuringFlush) {
775   // Simulate posting a delayed and an undelayed task.
776   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
777   auto delayed_sequence =
778       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
779   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
780   auto undelayed_sequence =
781       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
782 
783   // FlushForTesting() shouldn't return before the undelayed task runs.
784   CallFlushFromAnotherThread();
785   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
786   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
787 
788   // Run the delayed task.
789   RunAndPopNextTask(std::move(delayed_sequence));
790 
791   // FlushForTesting() shouldn't return since there is still a pending undelayed
792   // task.
793   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
794   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
795 
796   // Run the undelayed task.
797   RunAndPopNextTask(std::move(undelayed_sequence));
798 
799   // FlushForTesting() should now ESreturn.
800   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
801 }
802 
TEST_P(ThreadPoolTaskTrackerTest,RunDelayedTaskDuringFlushAsyncForTesting)803 TEST_P(ThreadPoolTaskTrackerTest, RunDelayedTaskDuringFlushAsyncForTesting) {
804   // Simulate posting a delayed and an undelayed task.
805   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
806   auto delayed_sequence =
807       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
808   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
809   auto undelayed_sequence =
810       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
811 
812   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
813   TestWaitableEvent event;
814   tracker_.FlushAsyncForTesting(
815       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
816   EXPECT_FALSE(event.IsSignaled());
817 
818   // Run the delayed task.
819   RunAndPopNextTask(std::move(delayed_sequence));
820 
821   // FlushAsyncForTesting() shouldn't callback since there is still a pending
822   // undelayed task.
823   EXPECT_FALSE(event.IsSignaled());
824 
825   // Run the undelayed task.
826   RunAndPopNextTask(std::move(undelayed_sequence));
827 
828   // FlushAsyncForTesting() should now callback.
829   event.Wait();
830 }
831 
TEST_P(ThreadPoolTaskTrackerTest,FlushAfterShutdown)832 TEST_P(ThreadPoolTaskTrackerTest, FlushAfterShutdown) {
833   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
834     return;
835 
836   // Simulate posting a task.
837   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
838   tracker_.WillPostTask(&undelayed_task, GetParam());
839 
840   // Shutdown() should return immediately since there are no pending
841   // BLOCK_SHUTDOWN tasks.
842   test::ShutdownTaskTracker(&tracker_);
843 
844   // FlushForTesting() should return immediately after shutdown, even if an
845   // undelayed task hasn't run.
846   tracker_.FlushForTesting();
847 }
848 
TEST_P(ThreadPoolTaskTrackerTest,FlushAfterShutdownAsync)849 TEST_P(ThreadPoolTaskTrackerTest, FlushAfterShutdownAsync) {
850   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
851     return;
852 
853   // Simulate posting a task.
854   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
855   tracker_.WillPostTask(&undelayed_task, GetParam());
856 
857   // Shutdown() should return immediately since there are no pending
858   // BLOCK_SHUTDOWN tasks.
859   test::ShutdownTaskTracker(&tracker_);
860 
861   // FlushForTesting() should callback immediately after shutdown, even if an
862   // undelayed task hasn't run.
863   bool called_back = false;
864   tracker_.FlushAsyncForTesting(
865       BindOnce([](bool* called_back) { *called_back = true; },
866                Unretained(&called_back)));
867   EXPECT_TRUE(called_back);
868 }
869 
TEST_P(ThreadPoolTaskTrackerTest,ShutdownDuringFlush)870 TEST_P(ThreadPoolTaskTrackerTest, ShutdownDuringFlush) {
871   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
872     return;
873 
874   // Simulate posting a task.
875   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
876   auto undelayed_sequence =
877       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
878 
879   // FlushForTesting() shouldn't return before the undelayed task runs or
880   // shutdown completes.
881   CallFlushFromAnotherThread();
882   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
883   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
884 
885   // Shutdown() should return immediately since there are no pending
886   // BLOCK_SHUTDOWN tasks.
887   test::ShutdownTaskTracker(&tracker_);
888 
889   // FlushForTesting() should now return, even if an undelayed task hasn't run.
890   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
891 }
892 
TEST_P(ThreadPoolTaskTrackerTest,ShutdownDuringFlushAsyncForTesting)893 TEST_P(ThreadPoolTaskTrackerTest, ShutdownDuringFlushAsyncForTesting) {
894   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
895     return;
896 
897   // Simulate posting a task.
898   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
899   auto undelayed_sequence =
900       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
901 
902   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs or
903   // shutdown completes.
904   TestWaitableEvent event;
905   tracker_.FlushAsyncForTesting(
906       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
907   EXPECT_FALSE(event.IsSignaled());
908 
909   // Shutdown() should return immediately since there are no pending
910   // BLOCK_SHUTDOWN tasks.
911   test::ShutdownTaskTracker(&tracker_);
912 
913   // FlushAsyncForTesting() should now callback, even if an undelayed task
914   // hasn't run.
915   event.Wait();
916 }
917 
TEST_P(ThreadPoolTaskTrackerTest,PostTasksDoNotBlockShutdown)918 TEST_P(ThreadPoolTaskTrackerTest, PostTasksDoNotBlockShutdown) {
919   // Simulate posting an undelayed task.
920   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
921   EXPECT_TRUE(tracker_.WillPostTask(&undelayed_task, GetParam()));
922 
923   // Since no sequence was queued, a call to Shutdown() should not hang.
924   test::ShutdownTaskTracker(&tracker_);
925 }
926 
927 // Verify that a delayed task does not block shutdown once it's run, regardless
928 // of its shutdown behavior.
TEST_P(ThreadPoolTaskTrackerTest,DelayedRunTasks)929 TEST_P(ThreadPoolTaskTrackerTest, DelayedRunTasks) {
930   // Simulate posting a delayed task.
931   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
932   auto sequence =
933       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
934   EXPECT_TRUE(sequence);
935 
936   RunAndPopNextTask(std::move(sequence));
937 
938   // Since the delayed task doesn't block shutdown, a call to Shutdown() should
939   // not hang.
940   test::ShutdownTaskTracker(&tracker_);
941 }
942 
943 INSTANTIATE_TEST_SUITE_P(
944     ContinueOnShutdown,
945     ThreadPoolTaskTrackerTest,
946     ::testing::Values(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
947 INSTANTIATE_TEST_SUITE_P(
948     SkipOnShutdown,
949     ThreadPoolTaskTrackerTest,
950     ::testing::Values(TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
951 INSTANTIATE_TEST_SUITE_P(
952     BlockShutdown,
953     ThreadPoolTaskTrackerTest,
954     ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN));
955 
956 namespace {
957 
ExpectSequenceToken(SequenceToken sequence_token)958 void ExpectSequenceToken(SequenceToken sequence_token) {
959   EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread());
960 }
961 
962 }  // namespace
963 
964 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token
965 // when a Task runs.
TEST_F(ThreadPoolTaskTrackerTest,CurrentSequenceToken)966 TEST_F(ThreadPoolTaskTrackerTest, CurrentSequenceToken) {
967   scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>(
968       TaskTraits(), nullptr, TaskSourceExecutionMode::kParallel);
969 
970   const SequenceToken sequence_token = sequence->token();
971   Task task(FROM_HERE, BindOnce(&ExpectSequenceToken, sequence_token),
972             TimeTicks::Now(), TimeDelta());
973   tracker_.WillPostTask(&task, sequence->shutdown_behavior());
974 
975   {
976     Sequence::Transaction sequence_transaction(sequence->BeginTransaction());
977     sequence_transaction.WillPushImmediateTask();
978     sequence_transaction.PushImmediateTask(std::move(task));
979 
980     EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid());
981   }
982 
983   test::QueueAndRunTaskSource(&tracker_, std::move(sequence));
984   EXPECT_FALSE(SequenceToken::GetForCurrentThread().IsValid());
985 }
986 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostAndRunBeforeShutdown)987 TEST_F(ThreadPoolTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) {
988   // Post and run tasks asynchronously.
989   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
990 
991   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
992     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
993         &tracker_,
994         MakeRefCounted<Sequence>(
995             TaskTraits{TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, nullptr,
996             TaskSourceExecutionMode::kParallel),
997         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
998         CreateTask()));
999     threads.back()->Start();
1000 
1001     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1002         &tracker_,
1003         MakeRefCounted<Sequence>(
1004             TaskTraits{TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, nullptr,
1005             TaskSourceExecutionMode::kParallel),
1006         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1007         CreateTask()));
1008     threads.back()->Start();
1009 
1010     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1011         &tracker_,
1012         MakeRefCounted<Sequence>(
1013             TaskTraits{TaskShutdownBehavior::BLOCK_SHUTDOWN}, nullptr,
1014             TaskSourceExecutionMode::kParallel),
1015         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1016         CreateTask()));
1017     threads.back()->Start();
1018   }
1019 
1020   for (const auto& thread : threads)
1021     thread->Join();
1022 
1023   // Expect all tasks to be executed.
1024   EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted());
1025 
1026   // Should return immediately because no tasks are blocking shutdown.
1027   test::ShutdownTaskTracker(&tracker_);
1028 }
1029 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostBeforeShutdownAndRunDuringShutdown)1030 TEST_F(ThreadPoolTaskTrackerTest,
1031        LoadWillPostBeforeShutdownAndRunDuringShutdown) {
1032   constexpr TaskTraits traits_continue_on_shutdown =
1033       TaskTraits(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
1034   constexpr TaskTraits traits_skip_on_shutdown =
1035       TaskTraits(TaskShutdownBehavior::SKIP_ON_SHUTDOWN);
1036   constexpr TaskTraits traits_block_shutdown =
1037       TaskTraits(TaskShutdownBehavior::BLOCK_SHUTDOWN);
1038 
1039   // Post tasks asynchronously.
1040   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads;
1041   {
1042     std::vector<scoped_refptr<Sequence>> sequences_continue_on_shutdown;
1043     std::vector<scoped_refptr<Sequence>> sequences_skip_on_shutdown;
1044     std::vector<scoped_refptr<Sequence>> sequences_block_shutdown;
1045     for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1046       sequences_continue_on_shutdown.push_back(
1047           MakeRefCounted<Sequence>(traits_continue_on_shutdown, nullptr,
1048                                    TaskSourceExecutionMode::kParallel));
1049       sequences_skip_on_shutdown.push_back(
1050           MakeRefCounted<Sequence>(traits_skip_on_shutdown, nullptr,
1051                                    TaskSourceExecutionMode::kParallel));
1052       sequences_block_shutdown.push_back(MakeRefCounted<Sequence>(
1053           traits_block_shutdown, nullptr, TaskSourceExecutionMode::kParallel));
1054     }
1055 
1056     for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1057       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1058           &tracker_, sequences_continue_on_shutdown[i],
1059           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1060       post_threads.back()->Start();
1061 
1062       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1063           &tracker_, sequences_skip_on_shutdown[i],
1064           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1065       post_threads.back()->Start();
1066 
1067       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1068           &tracker_, sequences_block_shutdown[i],
1069           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1070       post_threads.back()->Start();
1071     }
1072   }
1073 
1074   for (const auto& thread : post_threads)
1075     thread->Join();
1076 
1077   // Start shutdown and try to complete shutdown asynchronously.
1078   tracker_.StartShutdown();
1079   ExpectAsyncCompleteShutdownBlocks();
1080 
1081   // Run tasks asynchronously.
1082   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads;
1083   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1084     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1085         &tracker_, post_threads[i * 3]->TakeTaskSource()));
1086     run_threads.back()->Start();
1087 
1088     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1089         &tracker_, post_threads[i * 3 + 1]->TakeTaskSource()));
1090     run_threads.back()->Start();
1091 
1092     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1093         &tracker_, post_threads[i * 3 + 2]->TakeTaskSource()));
1094     run_threads.back()->Start();
1095   }
1096 
1097   for (const auto& thread : run_threads)
1098     thread->Join();
1099 
1100   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
1101 
1102   // Expect BLOCK_SHUTDOWN tasks to have been executed.
1103   EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
1104 }
1105 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostAndRunDuringShutdown)1106 TEST_F(ThreadPoolTaskTrackerTest, LoadWillPostAndRunDuringShutdown) {
1107   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
1108   // block shutdown.
1109   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
1110       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
1111   EXPECT_TRUE(block_shutdown_sequence);
1112 
1113   // Start shutdown and try to complete it asynchronously.
1114   tracker_.StartShutdown();
1115   ExpectAsyncCompleteShutdownBlocks();
1116 
1117   // Post and run tasks asynchronously.
1118   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
1119 
1120   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1121     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1122         &tracker_,
1123         MakeRefCounted<Sequence>(
1124             TaskTraits{TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, nullptr,
1125             TaskSourceExecutionMode::kParallel),
1126         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false,
1127         CreateTask()));
1128     threads.back()->Start();
1129 
1130     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1131         &tracker_,
1132         MakeRefCounted<Sequence>(
1133             TaskTraits{TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, nullptr,
1134             TaskSourceExecutionMode::kParallel),
1135         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false,
1136         CreateTask()));
1137     threads.back()->Start();
1138 
1139     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1140         &tracker_,
1141         MakeRefCounted<Sequence>(
1142             TaskTraits{TaskShutdownBehavior::BLOCK_SHUTDOWN}, nullptr,
1143             TaskSourceExecutionMode::kParallel),
1144         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1145         CreateTask()));
1146     threads.back()->Start();
1147   }
1148 
1149   for (const auto& thread : threads)
1150     thread->Join();
1151 
1152   // Expect BLOCK_SHUTDOWN tasks to have been executed.
1153   EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
1154 
1155   // Shutdown() shouldn't return before |block_shutdown_task| is executed.
1156   VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
1157 
1158   // Unblock shutdown by running |block_shutdown_task|.
1159   RunAndPopNextTask(std::move(block_shutdown_sequence));
1160   EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted());
1161   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
1162 }
1163 
1164 // Verify that RunAndPopNextTask() returns the sequence from which it ran a task
1165 // when it can be rescheduled.
TEST_F(ThreadPoolTaskTrackerTest,RunAndPopNextTaskReturnsSequenceToReschedule)1166 TEST_F(ThreadPoolTaskTrackerTest,
1167        RunAndPopNextTaskReturnsSequenceToReschedule) {
1168   TaskTraits default_traits;
1169   Task task_1(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
1170   EXPECT_TRUE(
1171       tracker_.WillPostTask(&task_1, default_traits.shutdown_behavior()));
1172   Task task_2(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
1173   EXPECT_TRUE(
1174       tracker_.WillPostTask(&task_2, default_traits.shutdown_behavior()));
1175 
1176   scoped_refptr<Sequence> sequence =
1177       test::CreateSequenceWithTask(std::move(task_1), default_traits);
1178   {
1179     auto transaction = sequence->BeginTransaction();
1180     transaction.WillPushImmediateTask();
1181     transaction.PushImmediateTask(std::move(task_2));
1182   }
1183   EXPECT_EQ(sequence,
1184             test::QueueAndRunTaskSource(&tracker_, sequence).Unregister());
1185 }
1186 
1187 namespace {
1188 
1189 class WaitAllowedTestThread : public SimpleThread {
1190  public:
WaitAllowedTestThread()1191   WaitAllowedTestThread() : SimpleThread("WaitAllowedTestThread") {}
1192   WaitAllowedTestThread(const WaitAllowedTestThread&) = delete;
1193   WaitAllowedTestThread& operator=(const WaitAllowedTestThread&) = delete;
1194 
1195  private:
Run()1196   void Run() override {
1197     auto task_tracker = std::make_unique<TaskTracker>();
1198 
1199     // Waiting is allowed by default. Expect TaskTracker to disallow it before
1200     // running a task without the WithBaseSyncPrimitives() trait.
1201     internal::AssertBaseSyncPrimitivesAllowed();
1202     Task task_without_sync_primitives(
1203         FROM_HERE, BindOnce([]() {
1204           EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
1205         }),
1206         TimeTicks::Now(), TimeDelta());
1207     TaskTraits default_traits;
1208     EXPECT_TRUE(task_tracker->WillPostTask(&task_without_sync_primitives,
1209                                            default_traits.shutdown_behavior()));
1210     auto sequence_without_sync_primitives = test::CreateSequenceWithTask(
1211         std::move(task_without_sync_primitives), default_traits);
1212     test::QueueAndRunTaskSource(task_tracker.get(),
1213                                 std::move(sequence_without_sync_primitives));
1214 
1215     // Expect TaskTracker to keep waiting allowed when running a task with the
1216     // WithBaseSyncPrimitives() trait.
1217     internal::AssertBaseSyncPrimitivesAllowed();
1218     Task task_with_sync_primitives(
1219         FROM_HERE, BindOnce([]() {
1220           // Shouldn't fail.
1221           internal::AssertBaseSyncPrimitivesAllowed();
1222         }),
1223         TimeTicks::Now(), TimeDelta());
1224     TaskTraits traits_with_sync_primitives =
1225         TaskTraits(WithBaseSyncPrimitives());
1226     EXPECT_TRUE(task_tracker->WillPostTask(
1227         &task_with_sync_primitives,
1228         traits_with_sync_primitives.shutdown_behavior()));
1229     auto sequence_with_sync_primitives = test::CreateSequenceWithTask(
1230         std::move(task_with_sync_primitives), traits_with_sync_primitives);
1231     test::QueueAndRunTaskSource(task_tracker.get(),
1232                                 std::move(sequence_with_sync_primitives));
1233 
1234     ScopedAllowBaseSyncPrimitivesForTesting
1235         allow_wait_in_task_tracker_destructor;
1236     task_tracker.reset();
1237   }
1238 };
1239 
1240 }  // namespace
1241 
1242 // Verify that AssertIOAllowed() succeeds only for a WithBaseSyncPrimitives()
1243 // task.
TEST(ThreadPoolTaskTrackerWaitAllowedTest,WaitAllowed)1244 TEST(ThreadPoolTaskTrackerWaitAllowedTest, WaitAllowed) {
1245   // Run the test on the separate thread since it is not possible to reset the
1246   // "wait allowed" bit of a thread without being a friend of
1247   // ThreadRestrictions.
1248   GTEST_FLAG_SET(death_test_style, "threadsafe");
1249   WaitAllowedTestThread wait_allowed_test_thread;
1250   wait_allowed_test_thread.Start();
1251   wait_allowed_test_thread.Join();
1252 }
1253 
1254 }  // namespace internal
1255 }  // namespace base
1256