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