Index: chromecast/base/alarm_manager.h |
diff --git a/chromecast/base/alarm_manager.h b/chromecast/base/alarm_manager.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..868d29277d0de7e8d41ae87e73186d5847835376 |
--- /dev/null |
+++ b/chromecast/base/alarm_manager.h |
@@ -0,0 +1,109 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CHROMECAST_BASE_ALARM_MANAGER_H_ |
+#define CHROMECAST_BASE_ALARM_MANAGER_H_ |
+ |
+#include <map> |
halliwell
2017/02/22 19:09:15
unused?
ryanchung
2017/02/22 19:39:39
Done.
|
+#include <queue> |
+#include <vector> |
+ |
+#include "base/callback_forward.h" |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/threading/thread.h" |
+#include "base/time/clock.h" |
+#include "base/timer/timer.h" |
halliwell
2017/02/22 19:09:15
nit, can just forward-declare for things held in u
ryanchung
2017/02/22 19:39:39
Done. thx.
|
+ |
+namespace chromecast { |
+ |
+// Alarm manager allows setting a task for wall clock time rather than for an |
+// elapsed amount of time. This is different from using long PostDelayedTasks |
+// that are sensitive to time changes, clock drift, and other factors. |
+// |
+// Alarm manager polls the wall clock time every 5 seconds. If the clock is |
+// equal or past the requested time, the alarm will fire. |
+// |
+// Any thread can add or remove alarms. The alarm will be fired on the original |
+// thread used to set the alarm. |
+// |
+// When an alarm is added to the alarm manager, the task is guaranteed to not |
+// run before the clock passes the requested time. The task may not run even if |
+// it is past the requested time if the software is suspended. However, once |
+// woken up, the event will fire within 5 seconds if the target time has passed. |
+class AlarmManager { |
+ public: |
+ // Construct and start the alarm manager. |
+ AlarmManager(); |
+ ~AlarmManager(); |
+ |
+ // For testing only. Allows setting a fake clock and using a custom task |
+ // runner. |
+ AlarmManager(std::unique_ptr<base::Clock> clock, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ |
+ // Add an alarm. |
+ // |task| will be executed at around |time|. |
+ void PostAlarmTask(const base::Closure& task, base::Time time); |
+ |
+ private: |
+ class AlarmInfo { |
+ public: |
+ AlarmInfo(const base::Closure& task, |
+ base::Time time, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ ~AlarmInfo(); |
+ |
+ const base::Closure task() const { return task_; } |
+ base::Time time() const { return time_; } |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner() const { |
+ return task_runner_; |
+ } |
+ |
+ private: |
+ const base::Closure task_; |
+ const base::Time time_; |
+ const scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ DISALLOW_COPY_AND_ASSIGN(AlarmInfo); |
+ }; |
+ |
+ // Check if an alarm should fire. |
+ void CheckAlarm(); |
+ // Add the alarm to the queue. |
+ void AddAlarm(const base::Closure& task, |
+ base::Time time, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ |
+ // Ordering alarms by earliest time. |
+ struct alarm_compare |
+ : public std::binary_function<std::unique_ptr<AlarmInfo>&, |
+ std::unique_ptr<AlarmInfo>&, |
+ bool> { |
+ bool operator()(const std::unique_ptr<AlarmInfo>& lhs, |
+ const std::unique_ptr<AlarmInfo>& rhs) const { |
+ return lhs->time() > rhs->time(); |
+ } |
+ }; |
+ |
+ // Store a list of the alarms to fire at a certain time. |
+ std::priority_queue<std::unique_ptr<AlarmInfo>, |
+ std::vector<std::unique_ptr<AlarmInfo>>, |
+ alarm_compare> |
+ next_alarm_; |
+ |
+ // Poller for wall clock time. |
+ std::unique_ptr<base::Clock> clock_; |
+ std::unique_ptr<base::Timer> clock_tick_timer_; |
+ std::unique_ptr<base::Thread> alarm_thread_; |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ |
+ base::WeakPtrFactory<AlarmManager> weak_factory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AlarmManager); |
+}; |
+ |
+} // namespace chromecast |
+ |
+#endif // CHROMECAST_BASE_ALARM_MANAGER_H_ |