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 10namespace base { 11 12DeferredSequencedTaskRunner::DeferredTask::DeferredTask() 13 : is_non_nestable(false) { 14} 15 16DeferredSequencedTaskRunner::DeferredTask::~DeferredTask() { 17} 18 19DeferredSequencedTaskRunner::DeferredSequencedTaskRunner( 20 const scoped_refptr<SequencedTaskRunner>& target_task_runner) 21 : started_(false), 22 target_task_runner_(target_task_runner) { 23} 24 25DeferredSequencedTaskRunner::~DeferredSequencedTaskRunner() { 26} 27 28bool 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 42bool DeferredSequencedTaskRunner::RunsTasksOnCurrentThread() const { 43 return target_task_runner_->RunsTasksOnCurrentThread(); 44} 45 46bool 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 61void 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 75void 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