Use appropriate EXPECT_EQ argument order for BookmarkModelTest assertions
[chromium-blink-merge.git] / components / timers / alarm_timer.cc
blob799a1ec7e98b63c9104b9a88f891cc4e6a9a1d9a
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.
5 #include "components/timers/alarm_timer.h"
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/timers/rtc_alarm.h"
14 namespace timers {
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());
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());
37 AlarmTimer::~AlarmTimer() {
38 Stop();
41 void AlarmTimer::Stop() {
42 if (!can_wake_from_suspend_) {
43 base::Timer::Stop();
44 return;
47 // Clear the running flag, stop the delegate, and delete the pending task.
48 base::Timer::set_is_running(false);
49 delegate_->Stop();
50 pending_task_.reset();
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;
60 if (!base::Timer::retain_user_task())
61 base::Timer::set_user_task(base::Closure());
64 void AlarmTimer::Reset() {
65 if (!can_wake_from_suspend_) {
66 base::Timer::Reset();
67 return;
70 DCHECK(!base::Timer::user_task().is_null());
71 DCHECK(!origin_message_loop_ ||
72 origin_message_loop_->task_runner()->RunsTasksOnCurrentThread());
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);
81 // Set up the pending task.
82 if (base::Timer::GetCurrentDelay() > base::TimeDelta::FromMicroseconds(0)) {
83 base::Timer::set_desired_run_time(
84 base::TimeTicks::Now() + base::Timer::GetCurrentDelay());
85 pending_task_.reset(new base::PendingTask(base::Timer::posted_from(),
86 base::Timer::user_task(),
87 base::Timer::desired_run_time(),
88 true /* nestable */));
89 } else {
90 base::Timer::set_desired_run_time(base::TimeTicks());
91 pending_task_.reset(new base::PendingTask(base::Timer::posted_from(),
92 base::Timer::user_task()));
94 base::MessageLoop::current()->task_annotator()->DidQueueTask(
95 "AlarmTimer::Reset", *pending_task_);
97 // Now start up the timer.
98 delegate_->Reset(base::Timer::GetCurrentDelay());
99 base::Timer::set_is_running(true);
102 void AlarmTimer::WillDestroyCurrentMessageLoop() {
103 Stop();
106 void AlarmTimer::OnTimerFired() {
107 if (!base::Timer::is_running())
108 return;
110 DCHECK(pending_task_.get());
112 // Take ownership of the pending user task, which is going to be cleared by
113 // the Stop() or Reset() functions below.
114 scoped_ptr<base::PendingTask> pending_user_task(pending_task_.Pass());
116 // Re-schedule or stop the timer as requested.
117 if (base::Timer::is_repeating())
118 Reset();
119 else
120 Stop();
122 // Now run the user task.
123 base::MessageLoop::current()->task_annotator()->RunTask(
124 "AlarmTimer::Reset", "AlarmTimer::OnTimerFired", *pending_user_task);
127 } // namespace timers