Home | History | Annotate | Download | only in fileapi
      1 // Copyright 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 "webkit/browser/fileapi/timed_task_helper.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/logging.h"
      9 #include "base/sequenced_task_runner.h"
     10 
     11 namespace fileapi {
     12 
     13 struct TimedTaskHelper::Tracker {
     14   explicit Tracker(TimedTaskHelper* timer) : timer(timer) {}
     15 
     16   ~Tracker() {
     17     if (timer)
     18       timer->tracker_ = NULL;
     19   }
     20 
     21   TimedTaskHelper* timer;
     22 };
     23 
     24 TimedTaskHelper::TimedTaskHelper(base::SequencedTaskRunner* task_runner)
     25     : task_runner_(task_runner),
     26       tracker_(NULL) {
     27 }
     28 
     29 TimedTaskHelper::~TimedTaskHelper() {
     30   DCHECK(task_runner_->RunsTasksOnCurrentThread());
     31   if (tracker_)
     32     tracker_->timer = NULL;
     33 }
     34 
     35 bool TimedTaskHelper::IsRunning() const {
     36   DCHECK(task_runner_->RunsTasksOnCurrentThread());
     37   return tracker_ != NULL;
     38 }
     39 
     40 void TimedTaskHelper::Start(
     41     const tracked_objects::Location& posted_from,
     42     base::TimeDelta delay,
     43     const base::Closure& user_task) {
     44   posted_from_ = posted_from;
     45   delay_ = delay;
     46   user_task_ = user_task;
     47   Reset();
     48 }
     49 
     50 void TimedTaskHelper::Reset() {
     51   DCHECK(task_runner_->RunsTasksOnCurrentThread());
     52   DCHECK(!user_task_.is_null());
     53   desired_run_time_ = base::TimeTicks::Now() + delay_;
     54 
     55   if (tracker_)
     56     return;
     57 
     58   // Initialize the tracker for the first time.
     59   tracker_ = new Tracker(this);
     60   PostDelayedTask(make_scoped_ptr(tracker_), delay_);
     61 }
     62 
     63 // static
     64 void TimedTaskHelper::Fired(scoped_ptr<Tracker> tracker) {
     65   if (!tracker->timer)
     66     return;
     67   TimedTaskHelper* timer = tracker->timer;
     68   timer->OnFired(tracker.Pass());
     69 }
     70 
     71 void TimedTaskHelper::OnFired(scoped_ptr<Tracker> tracker) {
     72   DCHECK(task_runner_->RunsTasksOnCurrentThread());
     73   base::TimeTicks now = base::TimeTicks::Now();
     74   if (desired_run_time_ > now) {
     75     PostDelayedTask(tracker.Pass(), desired_run_time_ - now);
     76     return;
     77   }
     78   tracker.reset();
     79   base::Closure task = user_task_;
     80   user_task_.Reset();
     81   task.Run();
     82 }
     83 
     84 void TimedTaskHelper::PostDelayedTask(scoped_ptr<Tracker> tracker,
     85                                       base::TimeDelta delay) {
     86   task_runner_->PostDelayedTask(
     87       posted_from_,
     88       base::Bind(&TimedTaskHelper::Fired, base::Passed(&tracker)),
     89       delay);
     90 }
     91 
     92 }  // namespace fileapi
     93