xref: /aosp_15_r20/external/cronet/base/task/thread_pool/task_tracker_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 or 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 // Posting a BLOCK_SHUTDOWN task after shutdown must be allowed from a
339 // CONTINUE_ON_SHUTDOWN. Ref. https://crbug.com/1499644#c9 - #c16.
340 // Note: This test can't be TEST_P as non-CONTINUE_ON_SHUTDOWN `poster` would
341 // hang in CompleteShutdown().
TEST_F(ThreadPoolTaskTrackerTest,PostAfterShutdownFromContinueOnShutdown)342 TEST_F(ThreadPoolTaskTrackerTest, PostAfterShutdownFromContinueOnShutdown) {
343   // Dummy.
344   Task task{CreateTask()};
345 
346   // Create a task that verifies the properties of this test.
347   TestWaitableEvent task_running;
348   TestWaitableEvent task_barrier;
349   Task poster(FROM_HERE, BindLambdaForTesting([&]() {
350                 task_running.Signal();
351                 task_barrier.Wait();
352 
353                 // No death when posting BLOCK_SHUTDOWN from
354                 // CONTINUE_ON_SHUTDOWN.
355                 EXPECT_TRUE(tracker_.IsShutdownComplete());
356                 EXPECT_FALSE(tracker_.WillPostTask(
357                     &task, TaskShutdownBehavior::BLOCK_SHUTDOWN));
358               }),
359               TimeTicks::Now(), TimeDelta());
360 
361   // Inform |task_tracker_| that |blocked_task| will be posted.
362   auto sequence = WillPostTaskAndQueueTaskSource(
363       std::move(poster), TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
364   EXPECT_TRUE(sequence);
365 
366   // Create a thread to run the task. Wait until the task starts running.
367   ThreadPostingAndRunningTask thread_running_task(&tracker_,
368                                                   std::move(sequence));
369   thread_running_task.Start();
370   task_running.Wait();
371 
372   // Fully shutdown `tracker_` Make sure it's complete before releasing the task
373   // to perform its test for CONTINUE_ON_SHUTDOWN.
374   test::ShutdownTaskTracker(&tracker_);
375 
376   // Unblock the task and wait for it to perform its test.
377   task_barrier.Signal();
378   thread_running_task.Join();
379 }
380 
381 // Verify that an undelayed task whose sequence wasn't queued does not block
382 // shutdown, regardless of its shutdown behavior.
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownQueueDuringShutdown)383 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownQueueDuringShutdown) {
384   // Simulate posting a undelayed task.
385   Task task{CreateTask()};
386   EXPECT_TRUE(tracker_.WillPostTask(&task, GetParam()));
387   auto sequence = test::CreateSequenceWithTask(std::move(task), {GetParam()});
388 
389   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
390   // block shutdown.
391   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
392       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
393   EXPECT_TRUE(block_shutdown_sequence);
394 
395   // Start shutdown and try to complete it asynchronously.
396   tracker_.StartShutdown();
397   ExpectAsyncCompleteShutdownBlocks();
398 
399   const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN;
400   if (should_run) {
401     test::QueueAndRunTaskSource(&tracker_, std::move(sequence));
402     EXPECT_EQ(1U, NumTasksExecuted());
403     VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
404   } else {
405     EXPECT_FALSE(tracker_.RegisterTaskSource(std::move(sequence)));
406   }
407 
408   // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task.
409   RunAndPopNextTask(std::move(block_shutdown_sequence));
410   EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted());
411   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
412 }
413 
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownRunDuringShutdown)414 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownRunDuringShutdown) {
415   // Inform |task_tracker_| that a task will be posted.
416   auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
417   EXPECT_TRUE(sequence);
418 
419   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
420   // block shutdown.
421   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
422       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
423   EXPECT_TRUE(block_shutdown_sequence);
424 
425   // Start shutdown and try to complete it asynchronously.
426   tracker_.StartShutdown();
427   ExpectAsyncCompleteShutdownBlocks();
428 
429   // Try to run |task|. It should only run it it's BLOCK_SHUTDOWN. Otherwise it
430   // should be discarded.
431   EXPECT_EQ(0U, NumTasksExecuted());
432   const bool should_run = GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN;
433 
434   RunAndPopNextTask(std::move(sequence));
435   EXPECT_EQ(should_run ? 1U : 0U, NumTasksExecuted());
436   VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
437 
438   // Unblock shutdown by running the remaining BLOCK_SHUTDOWN task.
439   RunAndPopNextTask(std::move(block_shutdown_sequence));
440   EXPECT_EQ(should_run ? 2U : 1U, NumTasksExecuted());
441   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
442 }
443 
TEST_P(ThreadPoolTaskTrackerTest,WillPostBeforeShutdownRunAfterShutdown)444 TEST_P(ThreadPoolTaskTrackerTest, WillPostBeforeShutdownRunAfterShutdown) {
445   // Inform |task_tracker_| that a task will be posted.
446   auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
447   EXPECT_TRUE(sequence);
448 
449   // Start shutdown.
450   tracker_.StartShutdown();
451   EXPECT_EQ(0U, NumTasksExecuted());
452 
453   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
454     // Verify that CompleteShutdown() blocks.
455     ExpectAsyncCompleteShutdownBlocks();
456 
457     // Run the task to unblock shutdown.
458     RunAndPopNextTask(std::move(sequence));
459     EXPECT_EQ(1U, NumTasksExecuted());
460     WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
461 
462     // It is not possible to test running a BLOCK_SHUTDOWN task posted before
463     // shutdown after shutdown because Shutdown() won't return if there are
464     // pending BLOCK_SHUTDOWN tasks.
465   } else {
466     tracker_.CompleteShutdown();
467 
468     // The task shouldn't be allowed to run after shutdown.
469     RunAndPopNextTask(std::move(sequence));
470     EXPECT_EQ(0U, NumTasksExecuted());
471   }
472 }
473 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAndRunDuringShutdown)474 TEST_P(ThreadPoolTaskTrackerTest, WillPostAndRunDuringShutdown) {
475   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
476   // block shutdown.
477   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
478       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
479   EXPECT_TRUE(block_shutdown_sequence);
480 
481   // Start shutdown.
482   tracker_.StartShutdown();
483 
484   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
485     // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted.
486     auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
487     EXPECT_TRUE(sequence);
488 
489     // Run the BLOCK_SHUTDOWN task.
490     EXPECT_EQ(0U, NumTasksExecuted());
491     RunAndPopNextTask(std::move(sequence));
492     EXPECT_EQ(1U, NumTasksExecuted());
493   } else {
494     // It shouldn't be allowed to post a non BLOCK_SHUTDOWN task.
495     auto sequence = WillPostTaskAndQueueTaskSource(CreateTask(), {GetParam()});
496     EXPECT_FALSE(sequence);
497 
498     // Don't try to run the task, because it wasn't allowed to be posted.
499   }
500 
501   // Verify that CompleteShutdown() blocks.
502   ExpectAsyncCompleteShutdownBlocks();
503 
504   // Unblock shutdown by running |block_shutdown_task|.
505   RunAndPopNextTask(std::move(block_shutdown_sequence));
506   EXPECT_EQ(GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN ? 2U : 1U,
507             NumTasksExecuted());
508   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
509 }
510 
TEST_P(ThreadPoolTaskTrackerTest,WillPostAfterShutdown)511 TEST_P(ThreadPoolTaskTrackerTest, WillPostAfterShutdown) {
512   test::ShutdownTaskTracker(&tracker_);
513 
514   Task task(CreateTask());
515 
516   // |task_tracker_| shouldn't allow a task to be posted after shutdown.
517   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN) {
518     // When the task tracker is allowed to fizzle block shutdown tasks,
519     // WillPostTask will return false and leak the task.
520     tracker_.BeginFizzlingBlockShutdownTasks();
521     EXPECT_FALSE(tracker_.WillPostTask(&task, GetParam()));
522     tracker_.EndFizzlingBlockShutdownTasks();
523 
524     // If a BLOCK_SHUTDOWN task is posted after shutdown without explicitly
525     // allowing BLOCK_SHUTDOWN task fizzling, WillPostTask DCHECKs to find
526     // ordering bugs.
527     EXPECT_DCHECK_DEATH(tracker_.WillPostTask(&task, GetParam()));
528   } else {
529     EXPECT_FALSE(tracker_.WillPostTask(&task, GetParam()));
530   }
531 }
532 
533 // Verify that BLOCK_SHUTDOWN and SKIP_ON_SHUTDOWN tasks can
534 // AssertSingletonAllowed() but CONTINUE_ON_SHUTDOWN tasks can't.
TEST_P(ThreadPoolTaskTrackerTest,SingletonAllowed)535 TEST_P(ThreadPoolTaskTrackerTest, SingletonAllowed) {
536   const bool can_use_singletons =
537       (GetParam() != TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
538 
539   Task task(FROM_HERE, BindOnce(&internal::AssertSingletonAllowed),
540             TimeTicks::Now(), TimeDelta());
541   auto sequence = WillPostTaskAndQueueTaskSource(std::move(task), {GetParam()});
542   EXPECT_TRUE(sequence);
543 
544   // Running the task should fail iff the task isn't allowed to use singletons.
545   if (can_use_singletons) {
546     EXPECT_FALSE(RunAndPopNextTask(std::move(sequence)));
547   } else {
548     EXPECT_DCHECK_DEATH({ RunAndPopNextTask(std::move(sequence)); });
549   }
550 }
551 
552 // Verify that AssertIOAllowed() succeeds only for a MayBlock() task.
TEST_P(ThreadPoolTaskTrackerTest,IOAllowed)553 TEST_P(ThreadPoolTaskTrackerTest, IOAllowed) {
554   // Allowed with MayBlock().
555   Task task_with_may_block(FROM_HERE, BindOnce([]() {
556                              // Shouldn't fail.
557                              ScopedBlockingCall scope_blocking_call(
558                                  FROM_HERE, BlockingType::WILL_BLOCK);
559                            }),
560                            TimeTicks::Now(), TimeDelta());
561   TaskTraits traits_with_may_block{MayBlock(), GetParam()};
562   auto sequence_with_may_block = WillPostTaskAndQueueTaskSource(
563       std::move(task_with_may_block), traits_with_may_block);
564   EXPECT_TRUE(sequence_with_may_block);
565   RunAndPopNextTask(std::move(sequence_with_may_block));
566 
567   // Disallowed in the absence of MayBlock().
568   Task task_without_may_block(FROM_HERE, BindOnce([]() {
569                                 EXPECT_DCHECK_DEATH({
570                                   ScopedBlockingCall scope_blocking_call(
571                                       FROM_HERE, BlockingType::WILL_BLOCK);
572                                 });
573                               }),
574                               TimeTicks::Now(), TimeDelta());
575   TaskTraits traits_without_may_block = TaskTraits(GetParam());
576   auto sequence_without_may_block = WillPostTaskAndQueueTaskSource(
577       std::move(task_without_may_block), traits_without_may_block);
578   EXPECT_TRUE(sequence_without_may_block);
579   RunAndPopNextTask(std::move(sequence_without_may_block));
580 }
581 
RunTaskRunnerCurrentDefaultHandleVerificationTask(TaskTracker * tracker,Task verify_task,TaskTraits traits,scoped_refptr<SequencedTaskRunner> task_runner,TaskSourceExecutionMode execution_mode)582 static void RunTaskRunnerCurrentDefaultHandleVerificationTask(
583     TaskTracker* tracker,
584     Task verify_task,
585     TaskTraits traits,
586     scoped_refptr<SequencedTaskRunner> task_runner,
587     TaskSourceExecutionMode execution_mode) {
588   // Pretend |verify_task| is posted to respect TaskTracker's contract.
589   EXPECT_TRUE(tracker->WillPostTask(&verify_task, traits.shutdown_behavior()));
590 
591   // Confirm that the test conditions are right (no
592   // task runner CurrentDefaultHandles set already).
593   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
594   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
595 
596   test::QueueAndRunTaskSource(
597       tracker,
598       test::CreateSequenceWithTask(std::move(verify_task), traits,
599                                    std::move(task_runner), execution_mode));
600 
601   // task runner CurrentDefaultHandle state is reset outside of task's scope.
602   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
603   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
604 }
605 
VerifyNoTaskRunnerCurrentDefaultHandle()606 static void VerifyNoTaskRunnerCurrentDefaultHandle() {
607   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
608   EXPECT_FALSE(SequencedTaskRunner::HasCurrentDefault());
609 }
610 
TEST_P(ThreadPoolTaskTrackerTest,TaskRunnerHandleIsNotSetOnParallel)611 TEST_P(ThreadPoolTaskTrackerTest, TaskRunnerHandleIsNotSetOnParallel) {
612   // Create a task that will verify that TaskRunnerHandles are not set in its
613   // scope per no TaskRunner ref being set to it.
614   Task verify_task(FROM_HERE, BindOnce(&VerifyNoTaskRunnerCurrentDefaultHandle),
615                    TimeTicks::Now(), TimeDelta());
616 
617   RunTaskRunnerCurrentDefaultHandleVerificationTask(
618       &tracker_, std::move(verify_task), TaskTraits(GetParam()), nullptr,
619       TaskSourceExecutionMode::kParallel);
620 }
621 
VerifySequencedTaskRunnerCurrentDefaultHandle(const SequencedTaskRunner * expected_task_runner)622 static void VerifySequencedTaskRunnerCurrentDefaultHandle(
623     const SequencedTaskRunner* expected_task_runner) {
624   EXPECT_FALSE(SingleThreadTaskRunner::HasCurrentDefault());
625   EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
626   EXPECT_EQ(expected_task_runner, SequencedTaskRunner::GetCurrentDefault());
627 }
628 
TEST_P(ThreadPoolTaskTrackerTest,SequencedTaskRunnerHasCurrentDefaultOnSequenced)629 TEST_P(ThreadPoolTaskTrackerTest,
630        SequencedTaskRunnerHasCurrentDefaultOnSequenced) {
631   scoped_refptr<SequencedTaskRunner> test_task_runner(new TestSimpleTaskRunner);
632 
633   // Create a task that will verify that
634   // SequencedTaskRunner::CurrentDefaultHandle is properly set to
635   // |test_task_runner| in its scope per |sequenced_task_runner_ref| being set
636   // to it.
637   Task verify_task(FROM_HERE,
638                    BindOnce(&VerifySequencedTaskRunnerCurrentDefaultHandle,
639                             Unretained(test_task_runner.get())),
640                    TimeTicks::Now(), TimeDelta());
641 
642   RunTaskRunnerCurrentDefaultHandleVerificationTask(
643       &tracker_, std::move(verify_task), TaskTraits(GetParam()),
644       std::move(test_task_runner), TaskSourceExecutionMode::kSequenced);
645 }
646 
VerifySingleThreadTaskRunnerCurrentDefaultHandle(const SingleThreadTaskRunner * expected_task_runner)647 static void VerifySingleThreadTaskRunnerCurrentDefaultHandle(
648     const SingleThreadTaskRunner* expected_task_runner) {
649   EXPECT_TRUE(SingleThreadTaskRunner::HasCurrentDefault());
650   // SequencedTaskRunner::CurrentDefaultHandle inherits
651   // SingleThreadTaskRunner::CurrentDefaultHandle for thread.
652   EXPECT_TRUE(SequencedTaskRunner::HasCurrentDefault());
653   EXPECT_EQ(expected_task_runner, SingleThreadTaskRunner::GetCurrentDefault());
654 }
655 
TEST_P(ThreadPoolTaskTrackerTest,SingleThreadTaskRunnerCurrentDefaultHandleIsSetOnSingleThreaded)656 TEST_P(ThreadPoolTaskTrackerTest,
657        SingleThreadTaskRunnerCurrentDefaultHandleIsSetOnSingleThreaded) {
658   scoped_refptr<SingleThreadTaskRunner> test_task_runner(
659       new TestSimpleTaskRunner);
660 
661   // Create a task that will verify that
662   // SingleThreadTaskRunner::CurrentDefaultHandle is properly set to
663   // |test_task_runner| in its scope per |single_thread_task_runner_ref| being
664   // set on it.
665   Task verify_task(FROM_HERE,
666                    BindOnce(&VerifySingleThreadTaskRunnerCurrentDefaultHandle,
667                             Unretained(test_task_runner.get())),
668                    TimeTicks::Now(), TimeDelta());
669 
670   RunTaskRunnerCurrentDefaultHandleVerificationTask(
671       &tracker_, std::move(verify_task), TaskTraits(GetParam()),
672       std::move(test_task_runner), TaskSourceExecutionMode::kSingleThread);
673 }
674 
TEST_P(ThreadPoolTaskTrackerTest,FlushPendingDelayedTask)675 TEST_P(ThreadPoolTaskTrackerTest, FlushPendingDelayedTask) {
676   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
677   tracker_.WillPostTask(&delayed_task, GetParam());
678   // FlushForTesting() should return even if the delayed task didn't run.
679   tracker_.FlushForTesting();
680 }
681 
TEST_P(ThreadPoolTaskTrackerTest,FlushAsyncForTestingPendingDelayedTask)682 TEST_P(ThreadPoolTaskTrackerTest, FlushAsyncForTestingPendingDelayedTask) {
683   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
684   tracker_.WillPostTask(&delayed_task, GetParam());
685   // FlushAsyncForTesting() should callback even if the delayed task didn't run.
686   bool called_back = false;
687   tracker_.FlushAsyncForTesting(
688       BindOnce([](bool* called_back) { *called_back = true; },
689                Unretained(&called_back)));
690   EXPECT_TRUE(called_back);
691 }
692 
TEST_P(ThreadPoolTaskTrackerTest,FlushPendingUndelayedTask)693 TEST_P(ThreadPoolTaskTrackerTest, FlushPendingUndelayedTask) {
694   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
695   auto undelayed_sequence =
696       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
697 
698   // FlushForTesting() shouldn't return before the undelayed task runs.
699   CallFlushFromAnotherThread();
700   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
701   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
702 
703   // FlushForTesting() should return after the undelayed task runs.
704   RunAndPopNextTask(std::move(undelayed_sequence));
705   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
706 }
707 
TEST_P(ThreadPoolTaskTrackerTest,MultipleFlushes)708 TEST_P(ThreadPoolTaskTrackerTest, MultipleFlushes) {
709   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
710   auto undelayed_sequence =
711       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
712 
713   // Multiple flushes should all unwind after the task runs.
714   CallFlushFromAnotherThread();
715   CallFlushFromAnotherThread();
716   CallFlushFromAnotherThread();
717   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
718   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
719 
720   RunAndPopNextTask(std::move(undelayed_sequence));
721   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
722 }
723 
TEST_P(ThreadPoolTaskTrackerTest,FlushAsyncForTestingPendingUndelayedTask)724 TEST_P(ThreadPoolTaskTrackerTest, FlushAsyncForTestingPendingUndelayedTask) {
725   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
726   auto undelayed_sequence =
727       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
728 
729   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
730   TestWaitableEvent event;
731   tracker_.FlushAsyncForTesting(
732       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
733   EXPECT_FALSE(event.IsSignaled());
734 
735   // FlushAsyncForTesting() should callback after the undelayed task runs.
736   RunAndPopNextTask(std::move(undelayed_sequence));
737   event.Wait();
738 }
739 
TEST_P(ThreadPoolTaskTrackerTest,MultipleFlushAsyncForTesting)740 TEST_P(ThreadPoolTaskTrackerTest, MultipleFlushAsyncForTesting) {
741   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
742   auto undelayed_sequence =
743       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
744 
745   TestWaitableEvent three_callbacks_ran;
746   auto on_flush_done = BarrierClosure(
747       3,
748       BindOnce(&TestWaitableEvent::Signal, Unretained(&three_callbacks_ran)));
749   tracker_.FlushAsyncForTesting(on_flush_done);
750   tracker_.FlushAsyncForTesting(on_flush_done);
751   tracker_.FlushAsyncForTesting(on_flush_done);
752   EXPECT_FALSE(three_callbacks_ran.IsSignaled());
753 
754   // FlushAsyncForTesting() should callback after the undelayed task runs.
755   RunAndPopNextTask(std::move(undelayed_sequence));
756   three_callbacks_ran.Wait();
757 }
758 
TEST_P(ThreadPoolTaskTrackerTest,PostTaskDuringFlush)759 TEST_P(ThreadPoolTaskTrackerTest, PostTaskDuringFlush) {
760   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
761   auto undelayed_sequence =
762       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
763 
764   // FlushForTesting() shouldn't return before the undelayed task runs.
765   CallFlushFromAnotherThread();
766   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
767   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
768 
769   // Simulate posting another undelayed task.
770   Task other_undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(),
771                             TimeDelta());
772   auto other_undelayed_sequence = WillPostTaskAndQueueTaskSource(
773       std::move(other_undelayed_task), {GetParam()});
774 
775   // Run the first undelayed task.
776   RunAndPopNextTask(std::move(undelayed_sequence));
777 
778   // FlushForTesting() shouldn't return before the second undelayed task runs.
779   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
780   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
781 
782   // FlushForTesting() should return after the second undelayed task runs.
783   RunAndPopNextTask(std::move(other_undelayed_sequence));
784   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
785 }
786 
TEST_P(ThreadPoolTaskTrackerTest,PostTaskDuringFlushAsyncForTesting)787 TEST_P(ThreadPoolTaskTrackerTest, PostTaskDuringFlushAsyncForTesting) {
788   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
789   auto undelayed_sequence =
790       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
791 
792   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
793   TestWaitableEvent event;
794   tracker_.FlushAsyncForTesting(
795       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
796   EXPECT_FALSE(event.IsSignaled());
797 
798   // Simulate posting another undelayed task.
799   Task other_undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(),
800                             TimeDelta());
801   auto other_undelayed_sequence = WillPostTaskAndQueueTaskSource(
802       std::move(other_undelayed_task), {GetParam()});
803 
804   // Run the first undelayed task.
805   RunAndPopNextTask(std::move(undelayed_sequence));
806 
807   // FlushAsyncForTesting() shouldn't callback before the second undelayed task
808   // runs.
809   EXPECT_FALSE(event.IsSignaled());
810 
811   // FlushAsyncForTesting() should callback after the second undelayed task
812   // runs.
813   RunAndPopNextTask(std::move(other_undelayed_sequence));
814   event.Wait();
815 }
816 
TEST_P(ThreadPoolTaskTrackerTest,RunDelayedTaskDuringFlush)817 TEST_P(ThreadPoolTaskTrackerTest, RunDelayedTaskDuringFlush) {
818   // Simulate posting a delayed and an undelayed task.
819   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
820   auto delayed_sequence =
821       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
822   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
823   auto undelayed_sequence =
824       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
825 
826   // FlushForTesting() shouldn't return before the undelayed task runs.
827   CallFlushFromAnotherThread();
828   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
829   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
830 
831   // Run the delayed task.
832   RunAndPopNextTask(std::move(delayed_sequence));
833 
834   // FlushForTesting() shouldn't return since there is still a pending undelayed
835   // task.
836   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
837   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
838 
839   // Run the undelayed task.
840   RunAndPopNextTask(std::move(undelayed_sequence));
841 
842   // FlushForTesting() should now ESreturn.
843   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
844 }
845 
TEST_P(ThreadPoolTaskTrackerTest,RunDelayedTaskDuringFlushAsyncForTesting)846 TEST_P(ThreadPoolTaskTrackerTest, RunDelayedTaskDuringFlushAsyncForTesting) {
847   // Simulate posting a delayed and an undelayed task.
848   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
849   auto delayed_sequence =
850       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
851   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
852   auto undelayed_sequence =
853       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
854 
855   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs.
856   TestWaitableEvent event;
857   tracker_.FlushAsyncForTesting(
858       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
859   EXPECT_FALSE(event.IsSignaled());
860 
861   // Run the delayed task.
862   RunAndPopNextTask(std::move(delayed_sequence));
863 
864   // FlushAsyncForTesting() shouldn't callback since there is still a pending
865   // undelayed task.
866   EXPECT_FALSE(event.IsSignaled());
867 
868   // Run the undelayed task.
869   RunAndPopNextTask(std::move(undelayed_sequence));
870 
871   // FlushAsyncForTesting() should now callback.
872   event.Wait();
873 }
874 
TEST_P(ThreadPoolTaskTrackerTest,FlushAfterShutdown)875 TEST_P(ThreadPoolTaskTrackerTest, FlushAfterShutdown) {
876   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
877     return;
878 
879   // Simulate posting a task.
880   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
881   tracker_.WillPostTask(&undelayed_task, GetParam());
882 
883   // Shutdown() should return immediately since there are no pending
884   // BLOCK_SHUTDOWN tasks.
885   test::ShutdownTaskTracker(&tracker_);
886 
887   // FlushForTesting() should return immediately after shutdown, even if an
888   // undelayed task hasn't run.
889   tracker_.FlushForTesting();
890 }
891 
TEST_P(ThreadPoolTaskTrackerTest,FlushAfterShutdownAsync)892 TEST_P(ThreadPoolTaskTrackerTest, FlushAfterShutdownAsync) {
893   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
894     return;
895 
896   // Simulate posting a task.
897   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
898   tracker_.WillPostTask(&undelayed_task, GetParam());
899 
900   // Shutdown() should return immediately since there are no pending
901   // BLOCK_SHUTDOWN tasks.
902   test::ShutdownTaskTracker(&tracker_);
903 
904   // FlushForTesting() should callback immediately after shutdown, even if an
905   // undelayed task hasn't run.
906   bool called_back = false;
907   tracker_.FlushAsyncForTesting(
908       BindOnce([](bool* called_back) { *called_back = true; },
909                Unretained(&called_back)));
910   EXPECT_TRUE(called_back);
911 }
912 
TEST_P(ThreadPoolTaskTrackerTest,ShutdownDuringFlush)913 TEST_P(ThreadPoolTaskTrackerTest, ShutdownDuringFlush) {
914   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
915     return;
916 
917   // Simulate posting a task.
918   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
919   auto undelayed_sequence =
920       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
921 
922   // FlushForTesting() shouldn't return before the undelayed task runs or
923   // shutdown completes.
924   CallFlushFromAnotherThread();
925   PlatformThread::Sleep(TestTimeouts::tiny_timeout());
926   VERIFY_ASYNC_FLUSHES_IN_PROGRESS();
927 
928   // Shutdown() should return immediately since there are no pending
929   // BLOCK_SHUTDOWN tasks.
930   test::ShutdownTaskTracker(&tracker_);
931 
932   // FlushForTesting() should now return, even if an undelayed task hasn't run.
933   WAIT_FOR_ASYNC_FLUSHES_RETURNED();
934 }
935 
TEST_P(ThreadPoolTaskTrackerTest,ShutdownDuringFlushAsyncForTesting)936 TEST_P(ThreadPoolTaskTrackerTest, ShutdownDuringFlushAsyncForTesting) {
937   if (GetParam() == TaskShutdownBehavior::BLOCK_SHUTDOWN)
938     return;
939 
940   // Simulate posting a task.
941   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
942   auto undelayed_sequence =
943       WillPostTaskAndQueueTaskSource(std::move(undelayed_task), {GetParam()});
944 
945   // FlushAsyncForTesting() shouldn't callback before the undelayed task runs or
946   // shutdown completes.
947   TestWaitableEvent event;
948   tracker_.FlushAsyncForTesting(
949       BindOnce(&TestWaitableEvent::Signal, Unretained(&event)));
950   EXPECT_FALSE(event.IsSignaled());
951 
952   // Shutdown() should return immediately since there are no pending
953   // BLOCK_SHUTDOWN tasks.
954   test::ShutdownTaskTracker(&tracker_);
955 
956   // FlushAsyncForTesting() should now callback, even if an undelayed task
957   // hasn't run.
958   event.Wait();
959 }
960 
TEST_P(ThreadPoolTaskTrackerTest,PostTasksDoNotBlockShutdown)961 TEST_P(ThreadPoolTaskTrackerTest, PostTasksDoNotBlockShutdown) {
962   // Simulate posting an undelayed task.
963   Task undelayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
964   EXPECT_TRUE(tracker_.WillPostTask(&undelayed_task, GetParam()));
965 
966   // Since no sequence was queued, a call to Shutdown() should not hang.
967   test::ShutdownTaskTracker(&tracker_);
968 }
969 
970 // Verify that a delayed task does not block shutdown once it's run, regardless
971 // of its shutdown behavior.
TEST_P(ThreadPoolTaskTrackerTest,DelayedRunTasks)972 TEST_P(ThreadPoolTaskTrackerTest, DelayedRunTasks) {
973   // Simulate posting a delayed task.
974   Task delayed_task(FROM_HERE, DoNothing(), TimeTicks::Now(), Days(1));
975   auto sequence =
976       WillPostTaskAndQueueTaskSource(std::move(delayed_task), {GetParam()});
977   EXPECT_TRUE(sequence);
978 
979   RunAndPopNextTask(std::move(sequence));
980 
981   // Since the delayed task doesn't block shutdown, a call to Shutdown() should
982   // not hang.
983   test::ShutdownTaskTracker(&tracker_);
984 }
985 
986 INSTANTIATE_TEST_SUITE_P(
987     ContinueOnShutdown,
988     ThreadPoolTaskTrackerTest,
989     ::testing::Values(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN));
990 INSTANTIATE_TEST_SUITE_P(
991     SkipOnShutdown,
992     ThreadPoolTaskTrackerTest,
993     ::testing::Values(TaskShutdownBehavior::SKIP_ON_SHUTDOWN));
994 INSTANTIATE_TEST_SUITE_P(
995     BlockShutdown,
996     ThreadPoolTaskTrackerTest,
997     ::testing::Values(TaskShutdownBehavior::BLOCK_SHUTDOWN));
998 
999 namespace {
1000 
ExpectSequenceToken(SequenceToken sequence_token)1001 void ExpectSequenceToken(SequenceToken sequence_token) {
1002   EXPECT_EQ(sequence_token, SequenceToken::GetForCurrentThread());
1003 }
1004 
1005 }  // namespace
1006 
1007 // Verify that SequenceToken::GetForCurrentThread() returns the Sequence's token
1008 // when a Task runs.
TEST_F(ThreadPoolTaskTrackerTest,CurrentSequenceToken)1009 TEST_F(ThreadPoolTaskTrackerTest, CurrentSequenceToken) {
1010   scoped_refptr<Sequence> sequence = MakeRefCounted<Sequence>(
1011       TaskTraits(), nullptr, TaskSourceExecutionMode::kParallel);
1012 
1013   const SequenceToken sequence_token = sequence->token();
1014   Task task(FROM_HERE, BindOnce(&ExpectSequenceToken, sequence_token),
1015             TimeTicks::Now(), TimeDelta());
1016   tracker_.WillPostTask(&task, sequence->shutdown_behavior());
1017 
1018   {
1019     Sequence::Transaction sequence_transaction(sequence->BeginTransaction());
1020     sequence_transaction.WillPushImmediateTask();
1021     sequence_transaction.PushImmediateTask(std::move(task));
1022 
1023     EXPECT_NE(SequenceToken::GetForCurrentThread(), sequence_token);
1024   }
1025 
1026   test::QueueAndRunTaskSource(&tracker_, std::move(sequence));
1027   EXPECT_NE(SequenceToken::GetForCurrentThread(), sequence_token);
1028 }
1029 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostAndRunBeforeShutdown)1030 TEST_F(ThreadPoolTaskTrackerTest, LoadWillPostAndRunBeforeShutdown) {
1031   // Post and run tasks asynchronously.
1032   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
1033 
1034   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1035     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1036         &tracker_,
1037         MakeRefCounted<Sequence>(
1038             TaskTraits{TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, nullptr,
1039             TaskSourceExecutionMode::kParallel),
1040         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1041         CreateTask()));
1042     threads.back()->Start();
1043 
1044     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1045         &tracker_,
1046         MakeRefCounted<Sequence>(
1047             TaskTraits{TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, nullptr,
1048             TaskSourceExecutionMode::kParallel),
1049         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1050         CreateTask()));
1051     threads.back()->Start();
1052 
1053     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1054         &tracker_,
1055         MakeRefCounted<Sequence>(
1056             TaskTraits{TaskShutdownBehavior::BLOCK_SHUTDOWN}, nullptr,
1057             TaskSourceExecutionMode::kParallel),
1058         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1059         CreateTask()));
1060     threads.back()->Start();
1061   }
1062 
1063   for (const auto& thread : threads)
1064     thread->Join();
1065 
1066   // Expect all tasks to be executed.
1067   EXPECT_EQ(kLoadTestNumIterations * 3, NumTasksExecuted());
1068 
1069   // Should return immediately because no tasks are blocking shutdown.
1070   test::ShutdownTaskTracker(&tracker_);
1071 }
1072 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostBeforeShutdownAndRunDuringShutdown)1073 TEST_F(ThreadPoolTaskTrackerTest,
1074        LoadWillPostBeforeShutdownAndRunDuringShutdown) {
1075   constexpr TaskTraits traits_continue_on_shutdown =
1076       TaskTraits(TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN);
1077   constexpr TaskTraits traits_skip_on_shutdown =
1078       TaskTraits(TaskShutdownBehavior::SKIP_ON_SHUTDOWN);
1079   constexpr TaskTraits traits_block_shutdown =
1080       TaskTraits(TaskShutdownBehavior::BLOCK_SHUTDOWN);
1081 
1082   // Post tasks asynchronously.
1083   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> post_threads;
1084   {
1085     std::vector<scoped_refptr<Sequence>> sequences_continue_on_shutdown;
1086     std::vector<scoped_refptr<Sequence>> sequences_skip_on_shutdown;
1087     std::vector<scoped_refptr<Sequence>> sequences_block_shutdown;
1088     for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1089       sequences_continue_on_shutdown.push_back(
1090           MakeRefCounted<Sequence>(traits_continue_on_shutdown, nullptr,
1091                                    TaskSourceExecutionMode::kParallel));
1092       sequences_skip_on_shutdown.push_back(
1093           MakeRefCounted<Sequence>(traits_skip_on_shutdown, nullptr,
1094                                    TaskSourceExecutionMode::kParallel));
1095       sequences_block_shutdown.push_back(MakeRefCounted<Sequence>(
1096           traits_block_shutdown, nullptr, TaskSourceExecutionMode::kParallel));
1097     }
1098 
1099     for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1100       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1101           &tracker_, sequences_continue_on_shutdown[i],
1102           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1103       post_threads.back()->Start();
1104 
1105       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1106           &tracker_, sequences_skip_on_shutdown[i],
1107           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1108       post_threads.back()->Start();
1109 
1110       post_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1111           &tracker_, sequences_block_shutdown[i],
1112           ThreadPostingAndRunningTask::Action::WILL_POST, true, CreateTask()));
1113       post_threads.back()->Start();
1114     }
1115   }
1116 
1117   for (const auto& thread : post_threads)
1118     thread->Join();
1119 
1120   // Start shutdown and try to complete shutdown asynchronously.
1121   tracker_.StartShutdown();
1122   ExpectAsyncCompleteShutdownBlocks();
1123 
1124   // Run tasks asynchronously.
1125   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> run_threads;
1126   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1127     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1128         &tracker_, post_threads[i * 3]->TakeTaskSource()));
1129     run_threads.back()->Start();
1130 
1131     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1132         &tracker_, post_threads[i * 3 + 1]->TakeTaskSource()));
1133     run_threads.back()->Start();
1134 
1135     run_threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1136         &tracker_, post_threads[i * 3 + 2]->TakeTaskSource()));
1137     run_threads.back()->Start();
1138   }
1139 
1140   for (const auto& thread : run_threads)
1141     thread->Join();
1142 
1143   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
1144 
1145   // Expect BLOCK_SHUTDOWN tasks to have been executed.
1146   EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
1147 }
1148 
TEST_F(ThreadPoolTaskTrackerTest,LoadWillPostAndRunDuringShutdown)1149 TEST_F(ThreadPoolTaskTrackerTest, LoadWillPostAndRunDuringShutdown) {
1150   // Inform |task_tracker_| that a BLOCK_SHUTDOWN task will be posted just to
1151   // block shutdown.
1152   auto block_shutdown_sequence = WillPostTaskAndQueueTaskSource(
1153       CreateTask(), {TaskShutdownBehavior::BLOCK_SHUTDOWN});
1154   EXPECT_TRUE(block_shutdown_sequence);
1155 
1156   // Start shutdown and try to complete it asynchronously.
1157   tracker_.StartShutdown();
1158   ExpectAsyncCompleteShutdownBlocks();
1159 
1160   // Post and run tasks asynchronously.
1161   std::vector<std::unique_ptr<ThreadPostingAndRunningTask>> threads;
1162 
1163   for (size_t i = 0; i < kLoadTestNumIterations; ++i) {
1164     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1165         &tracker_,
1166         MakeRefCounted<Sequence>(
1167             TaskTraits{TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, nullptr,
1168             TaskSourceExecutionMode::kParallel),
1169         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false,
1170         CreateTask()));
1171     threads.back()->Start();
1172 
1173     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1174         &tracker_,
1175         MakeRefCounted<Sequence>(
1176             TaskTraits{TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, nullptr,
1177             TaskSourceExecutionMode::kParallel),
1178         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, false,
1179         CreateTask()));
1180     threads.back()->Start();
1181 
1182     threads.push_back(std::make_unique<ThreadPostingAndRunningTask>(
1183         &tracker_,
1184         MakeRefCounted<Sequence>(
1185             TaskTraits{TaskShutdownBehavior::BLOCK_SHUTDOWN}, nullptr,
1186             TaskSourceExecutionMode::kParallel),
1187         ThreadPostingAndRunningTask::Action::WILL_POST_AND_RUN, true,
1188         CreateTask()));
1189     threads.back()->Start();
1190   }
1191 
1192   for (const auto& thread : threads)
1193     thread->Join();
1194 
1195   // Expect BLOCK_SHUTDOWN tasks to have been executed.
1196   EXPECT_EQ(kLoadTestNumIterations, NumTasksExecuted());
1197 
1198   // Shutdown() shouldn't return before |block_shutdown_task| is executed.
1199   VERIFY_ASYNC_SHUTDOWN_IN_PROGRESS();
1200 
1201   // Unblock shutdown by running |block_shutdown_task|.
1202   RunAndPopNextTask(std::move(block_shutdown_sequence));
1203   EXPECT_EQ(kLoadTestNumIterations + 1, NumTasksExecuted());
1204   WAIT_FOR_ASYNC_SHUTDOWN_COMPLETED();
1205 }
1206 
1207 // Verify that RunAndPopNextTask() returns the sequence from which it ran a task
1208 // when it can be rescheduled.
TEST_F(ThreadPoolTaskTrackerTest,RunAndPopNextTaskReturnsSequenceToReschedule)1209 TEST_F(ThreadPoolTaskTrackerTest,
1210        RunAndPopNextTaskReturnsSequenceToReschedule) {
1211   TaskTraits default_traits;
1212   Task task_1(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
1213   EXPECT_TRUE(
1214       tracker_.WillPostTask(&task_1, default_traits.shutdown_behavior()));
1215   Task task_2(FROM_HERE, DoNothing(), TimeTicks::Now(), TimeDelta());
1216   EXPECT_TRUE(
1217       tracker_.WillPostTask(&task_2, default_traits.shutdown_behavior()));
1218 
1219   scoped_refptr<Sequence> sequence =
1220       test::CreateSequenceWithTask(std::move(task_1), default_traits);
1221   {
1222     auto transaction = sequence->BeginTransaction();
1223     transaction.WillPushImmediateTask();
1224     transaction.PushImmediateTask(std::move(task_2));
1225   }
1226   EXPECT_EQ(sequence,
1227             test::QueueAndRunTaskSource(&tracker_, sequence).Unregister());
1228 }
1229 
1230 namespace {
1231 
1232 class WaitAllowedTestThread : public SimpleThread {
1233  public:
WaitAllowedTestThread()1234   WaitAllowedTestThread() : SimpleThread("WaitAllowedTestThread") {}
1235   WaitAllowedTestThread(const WaitAllowedTestThread&) = delete;
1236   WaitAllowedTestThread& operator=(const WaitAllowedTestThread&) = delete;
1237 
1238  private:
Run()1239   void Run() override {
1240     auto task_tracker = std::make_unique<TaskTracker>();
1241 
1242     // Waiting is allowed by default. Expect TaskTracker to disallow it before
1243     // running a task without the WithBaseSyncPrimitives() trait.
1244     internal::AssertBaseSyncPrimitivesAllowed();
1245     Task task_without_sync_primitives(
1246         FROM_HERE, BindOnce([]() {
1247           EXPECT_DCHECK_DEATH({ internal::AssertBaseSyncPrimitivesAllowed(); });
1248         }),
1249         TimeTicks::Now(), TimeDelta());
1250     TaskTraits default_traits;
1251     EXPECT_TRUE(task_tracker->WillPostTask(&task_without_sync_primitives,
1252                                            default_traits.shutdown_behavior()));
1253     auto sequence_without_sync_primitives = test::CreateSequenceWithTask(
1254         std::move(task_without_sync_primitives), default_traits);
1255     test::QueueAndRunTaskSource(task_tracker.get(),
1256                                 std::move(sequence_without_sync_primitives));
1257 
1258     // Expect TaskTracker to keep waiting allowed when running a task with the
1259     // WithBaseSyncPrimitives() trait.
1260     internal::AssertBaseSyncPrimitivesAllowed();
1261     Task task_with_sync_primitives(
1262         FROM_HERE, BindOnce([]() {
1263           // Shouldn't fail.
1264           internal::AssertBaseSyncPrimitivesAllowed();
1265         }),
1266         TimeTicks::Now(), TimeDelta());
1267     TaskTraits traits_with_sync_primitives =
1268         TaskTraits(WithBaseSyncPrimitives());
1269     EXPECT_TRUE(task_tracker->WillPostTask(
1270         &task_with_sync_primitives,
1271         traits_with_sync_primitives.shutdown_behavior()));
1272     auto sequence_with_sync_primitives = test::CreateSequenceWithTask(
1273         std::move(task_with_sync_primitives), traits_with_sync_primitives);
1274     test::QueueAndRunTaskSource(task_tracker.get(),
1275                                 std::move(sequence_with_sync_primitives));
1276 
1277     ScopedAllowBaseSyncPrimitivesForTesting
1278         allow_wait_in_task_tracker_destructor;
1279     task_tracker.reset();
1280   }
1281 };
1282 
1283 }  // namespace
1284 
1285 // Verify that AssertIOAllowed() succeeds only for a WithBaseSyncPrimitives()
1286 // task.
TEST(ThreadPoolTaskTrackerWaitAllowedTest,WaitAllowed)1287 TEST(ThreadPoolTaskTrackerWaitAllowedTest, WaitAllowed) {
1288   // Run the test on the separate thread since it is not possible to reset the
1289   // "wait allowed" bit of a thread without being a friend of
1290   // ThreadRestrictions.
1291   GTEST_FLAG_SET(death_test_style, "threadsafe");
1292   WaitAllowedTestThread wait_allowed_test_thread;
1293   wait_allowed_test_thread.Start();
1294   wait_allowed_test_thread.Join();
1295 }
1296 
1297 }  // namespace internal
1298 }  // namespace base
1299