• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
Trackerfileapi::TimedTaskHelper::Tracker14   explicit Tracker(TimedTaskHelper* timer) : timer(timer) {}
15 
~Trackerfileapi::TimedTaskHelper::Tracker16   ~Tracker() {
17     if (timer)
18       timer->tracker_ = NULL;
19   }
20 
21   TimedTaskHelper* timer;
22 };
23 
TimedTaskHelper(base::SequencedTaskRunner * task_runner)24 TimedTaskHelper::TimedTaskHelper(base::SequencedTaskRunner* task_runner)
25     : task_runner_(task_runner),
26       tracker_(NULL) {
27 }
28 
~TimedTaskHelper()29 TimedTaskHelper::~TimedTaskHelper() {
30   DCHECK(task_runner_->RunsTasksOnCurrentThread());
31   if (tracker_)
32     tracker_->timer = NULL;
33 }
34 
IsRunning() const35 bool TimedTaskHelper::IsRunning() const {
36   DCHECK(task_runner_->RunsTasksOnCurrentThread());
37   return tracker_ != NULL;
38 }
39 
Start(const tracked_objects::Location & posted_from,base::TimeDelta delay,const base::Closure & user_task)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 
Reset()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
Fired(scoped_ptr<Tracker> tracker)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 
OnFired(scoped_ptr<Tracker> tracker)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 
PostDelayedTask(scoped_ptr<Tracker> tracker,base::TimeDelta delay)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