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 }
     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