Home | History | Annotate | Download | only in test
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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/test/test_simple_task_runner.h"
      6 
      7 #include <utility>
      8 
      9 #include "base/logging.h"
     10 #include "base/memory/ptr_util.h"
     11 #include "base/threading/thread_task_runner_handle.h"
     12 
     13 namespace base {
     14 
     15 TestSimpleTaskRunner::TestSimpleTaskRunner() = default;
     16 
     17 TestSimpleTaskRunner::~TestSimpleTaskRunner() = default;
     18 
     19 bool TestSimpleTaskRunner::PostDelayedTask(const Location& from_here,
     20                                            OnceClosure task,
     21                                            TimeDelta delay) {
     22   AutoLock auto_lock(lock_);
     23   pending_tasks_.push_back(TestPendingTask(from_here, std::move(task),
     24                                            TimeTicks(), delay,
     25                                            TestPendingTask::NESTABLE));
     26   return true;
     27 }
     28 
     29 bool TestSimpleTaskRunner::PostNonNestableDelayedTask(const Location& from_here,
     30                                                       OnceClosure task,
     31                                                       TimeDelta delay) {
     32   AutoLock auto_lock(lock_);
     33   pending_tasks_.push_back(TestPendingTask(from_here, std::move(task),
     34                                            TimeTicks(), delay,
     35                                            TestPendingTask::NON_NESTABLE));
     36   return true;
     37 }
     38 
     39 // TODO(gab): Use SequenceToken here to differentiate between tasks running in
     40 // the scope of this TestSimpleTaskRunner and other task runners sharing this
     41 // thread. http://crbug.com/631186
     42 bool TestSimpleTaskRunner::RunsTasksInCurrentSequence() const {
     43   return thread_ref_ == PlatformThread::CurrentRef();
     44 }
     45 
     46 base::circular_deque<TestPendingTask> TestSimpleTaskRunner::TakePendingTasks() {
     47   AutoLock auto_lock(lock_);
     48   return std::move(pending_tasks_);
     49 }
     50 
     51 size_t TestSimpleTaskRunner::NumPendingTasks() const {
     52   AutoLock auto_lock(lock_);
     53   return pending_tasks_.size();
     54 }
     55 
     56 bool TestSimpleTaskRunner::HasPendingTask() const {
     57   AutoLock auto_lock(lock_);
     58   return !pending_tasks_.empty();
     59 }
     60 
     61 base::TimeDelta TestSimpleTaskRunner::NextPendingTaskDelay() const {
     62   AutoLock auto_lock(lock_);
     63   return pending_tasks_.front().GetTimeToRun() - base::TimeTicks();
     64 }
     65 
     66 base::TimeDelta TestSimpleTaskRunner::FinalPendingTaskDelay() const {
     67   AutoLock auto_lock(lock_);
     68   return pending_tasks_.back().GetTimeToRun() - base::TimeTicks();
     69 }
     70 
     71 void TestSimpleTaskRunner::ClearPendingTasks() {
     72   AutoLock auto_lock(lock_);
     73   pending_tasks_.clear();
     74 }
     75 
     76 void TestSimpleTaskRunner::RunPendingTasks() {
     77   DCHECK(RunsTasksInCurrentSequence());
     78 
     79   // Swap with a local variable to avoid re-entrancy problems.
     80   base::circular_deque<TestPendingTask> tasks_to_run;
     81   {
     82     AutoLock auto_lock(lock_);
     83     tasks_to_run.swap(pending_tasks_);
     84   }
     85 
     86   // Multiple test task runners can share the same thread for determinism in
     87   // unit tests. Make sure this TestSimpleTaskRunner's tasks run in its scope.
     88   ScopedClosureRunner undo_override;
     89   if (!ThreadTaskRunnerHandle::IsSet() ||
     90       ThreadTaskRunnerHandle::Get() != this) {
     91     undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this);
     92   }
     93 
     94   for (auto& task : tasks_to_run)
     95     std::move(task.task).Run();
     96 }
     97 
     98 void TestSimpleTaskRunner::RunUntilIdle() {
     99   while (HasPendingTask())
    100     RunPendingTasks();
    101 }
    102 
    103 }  // namespace base
    104