1 // Copyright (c) 2013 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/deferred_sequenced_task_runner.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 10 namespace base { 11 12 DeferredSequencedTaskRunner::DeferredTask::DeferredTask() { 13 } 14 15 DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() { 16 } 17 18 DeferredSequencedTaskRunner::DeferredSequencedTaskRunner( 19 const scoped_refptr<SequencedTaskRunner>& target_task_runner) 20 : started_(false), 21 target_task_runner_(target_task_runner) { 22 } 23 24 DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() { 25 } 26 27 bool DeferredSequencedTaskRunner::PostDelayedTask( 28 const tracked_objects::Location& from_here, 29 const Closure& task, 30 TimeDelta delay) { 31 AutoLock lock(lock_); 32 if (started_) { 33 DCHECK(deferred_tasks_queue_.empty()); 34 return target_task_runner_->PostDelayedTask(from_here, task, delay); 35 } 36 37 QueueDeferredTask(from_here, task, delay, false /* is_non_nestable */); 38 return true; 39 } 40 41 bool DeferredSequencedTaskRunner::RunsTasksOnCurrentThread() const { 42 return target_task_runner_->RunsTasksOnCurrentThread(); 43 } 44 45 bool DeferredSequencedTaskRunner::PostNonNestableDelayedTask( 46 const tracked_objects::Location& from_here, 47 const Closure& task, 48 TimeDelta delay) { 49 AutoLock lock(lock_); 50 if (started_) { 51 DCHECK(deferred_tasks_queue_.empty()); 52 return target_task_runner_->PostNonNestableDelayedTask(from_here, 53 task, 54 delay); 55 } 56 QueueDeferredTask(from_here, task, delay, true /* is_non_nestable */); 57 return true; 58 } 59 60 void DeferredSequencedTaskRunner::QueueDeferredTask( 61 const tracked_objects::Location& from_here, 62 const Closure& task, 63 TimeDelta delay, 64 bool is_non_nestable) { 65 DeferredTask deferred_task; 66 deferred_task.posted_from = from_here; 67 deferred_task.task = task; 68 deferred_task.delay = delay; 69 deferred_task.is_non_nestable = is_non_nestable; 70 deferred_tasks_queue_.push_back(deferred_task); 71 } 72 73 74 void DeferredSequencedTaskRunner::Start() { 75 AutoLock lock(lock_); 76 DCHECK(!started_); 77 started_ = true; 78 for (std::vector<DeferredTask>::iterator i = deferred_tasks_queue_.begin(); 79 i != deferred_tasks_queue_.end(); 80 ++i) { 81 const DeferredTask& task = *i; 82 if (task.is_non_nestable) { 83 target_task_runner_->PostNonNestableDelayedTask(task.posted_from, 84 task.task, 85 task.delay); 86 } else { 87 target_task_runner_->PostDelayedTask(task.posted_from, 88 task.task, 89 task.delay); 90 } 91 // Replace the i-th element in the |deferred_tasks_queue_| with an empty 92 // |DelayedTask| to ensure that |task| is destroyed before the next task 93 // is posted. 94 *i = DeferredTask(); 95 } 96 deferred_tasks_queue_.clear(); 97 } 98 99 } // namespace base 100