Home | History | Annotate | Download | only in base
      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