| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright 2014 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 "components/timer/alarm_timer.h" | 
|  | 6 | 
|  | 7 #include "base/bind.h" | 
|  | 8 #include "base/bind_helpers.h" | 
|  | 9 #include "base/files/file_util.h" | 
|  | 10 #include "base/logging.h" | 
|  | 11 #include "base/pending_task.h" | 
|  | 12 #include "components/timer/rtc_alarm.h" | 
|  | 13 | 
|  | 14 namespace timer { | 
|  | 15 | 
|  | 16 AlarmTimer::AlarmTimer(bool retain_user_task, bool is_repeating) | 
|  | 17     : base::Timer(retain_user_task, is_repeating), | 
|  | 18       delegate_(new RtcAlarm()), | 
|  | 19       can_wake_from_suspend_(false), | 
|  | 20       origin_message_loop_(NULL), | 
|  | 21       weak_factory_(this) { | 
|  | 22   can_wake_from_suspend_ = delegate_->Init(weak_factory_.GetWeakPtr()); | 
|  | 23 } | 
|  | 24 | 
|  | 25 AlarmTimer::AlarmTimer(const tracked_objects::Location& posted_from, | 
|  | 26                        base::TimeDelta delay, | 
|  | 27                        const base::Closure& user_task, | 
|  | 28                        bool is_repeating) | 
|  | 29     : base::Timer(posted_from, delay, user_task, is_repeating), | 
|  | 30       delegate_(new RtcAlarm()), | 
|  | 31       can_wake_from_suspend_(false), | 
|  | 32       origin_message_loop_(NULL), | 
|  | 33       weak_factory_(this) { | 
|  | 34   can_wake_from_suspend_ = delegate_->Init(weak_factory_.GetWeakPtr()); | 
|  | 35 } | 
|  | 36 | 
|  | 37 AlarmTimer::~AlarmTimer() { | 
|  | 38   Stop(); | 
|  | 39 } | 
|  | 40 | 
|  | 41 void AlarmTimer::Stop() { | 
|  | 42   if (!can_wake_from_suspend_) { | 
|  | 43     base::Timer::Stop(); | 
|  | 44     return; | 
|  | 45   } | 
|  | 46 | 
|  | 47   // Clear the running flag, stop the delegate, and delete the pending task. | 
|  | 48   is_running_ = false; | 
|  | 49   delegate_->Stop(); | 
|  | 50   pending_task_.reset(); | 
|  | 51 | 
|  | 52   // Stop is called when the AlarmTimer is destroyed so we need to remove | 
|  | 53   // ourselves as a MessageLoop::DestructionObserver to prevent a segfault | 
|  | 54   // later. | 
|  | 55   if (origin_message_loop_) { | 
|  | 56     origin_message_loop_->RemoveDestructionObserver(this); | 
|  | 57     origin_message_loop_ = NULL; | 
|  | 58   } | 
|  | 59 | 
|  | 60   if (!retain_user_task_) | 
|  | 61     user_task_.Reset(); | 
|  | 62 } | 
|  | 63 | 
|  | 64 void AlarmTimer::Reset() { | 
|  | 65   if (!can_wake_from_suspend_) { | 
|  | 66     base::Timer::Reset(); | 
|  | 67     return; | 
|  | 68   } | 
|  | 69 | 
|  | 70   DCHECK(!user_task_.is_null()); | 
|  | 71   DCHECK(!origin_message_loop_ || | 
|  | 72          origin_message_loop_->task_runner()->RunsTasksOnCurrentThread()); | 
|  | 73 | 
|  | 74   // Make sure that the timer will stop if the underlying message loop is | 
|  | 75   // destroyed. | 
|  | 76   if (!origin_message_loop_) { | 
|  | 77     origin_message_loop_ = base::MessageLoop::current(); | 
|  | 78     origin_message_loop_->AddDestructionObserver(this); | 
|  | 79   } | 
|  | 80 | 
|  | 81   // Set up the pending task. | 
|  | 82   if (delay_ == base::TimeDelta()) { | 
|  | 83     desired_run_time_ = base::TimeTicks(); | 
|  | 84     pending_task_.reset(new base::PendingTask(posted_from_, user_task_)); | 
|  | 85   } else { | 
|  | 86     desired_run_time_ = base::TimeTicks::Now() + delay_; | 
|  | 87     pending_task_.reset(new base::PendingTask( | 
|  | 88         posted_from_, user_task_, desired_run_time_, true)); | 
|  | 89   } | 
|  | 90   base::MessageLoop::current()->task_annotator()->DidQueueTask( | 
|  | 91       "AlarmTimer::Reset", *pending_task_); | 
|  | 92 | 
|  | 93   // Now start up the timer. | 
|  | 94   delegate_->Reset(delay_); | 
|  | 95   is_running_ = true; | 
|  | 96 } | 
|  | 97 | 
|  | 98 void AlarmTimer::WillDestroyCurrentMessageLoop() { | 
|  | 99   Stop(); | 
|  | 100 } | 
|  | 101 | 
|  | 102 void AlarmTimer::OnTimerFired() { | 
|  | 103   if (!is_running_) | 
|  | 104     return; | 
|  | 105 | 
|  | 106   DCHECK(pending_task_.get()); | 
|  | 107 | 
|  | 108   // Take ownership of the pending user task, which is going to be cleared by | 
|  | 109   // the Stop() or Reset() functions below. | 
|  | 110   scoped_ptr<base::PendingTask> pending_user_task(pending_task_.Pass()); | 
|  | 111 | 
|  | 112   // Re-schedule or stop the timer as requested. | 
|  | 113   if (is_repeating_) | 
|  | 114     Reset(); | 
|  | 115   else | 
|  | 116     Stop(); | 
|  | 117 | 
|  | 118   // Now lets run the user task. | 
|  | 119   base::MessageLoop::current()->task_annotator()->RunTask( | 
|  | 120       "AlarmTimer::Reset", "AlarmTimer::OnTimerFired", *pending_user_task); | 
|  | 121 } | 
|  | 122 | 
|  | 123 }  // namespace timer | 
| OLD | NEW | 
|---|