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