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..df3c8a5aecd26f75a48cdd9e71b855d3241dd990 |
--- /dev/null |
+++ b/chromecast/base/alarm_manager.h |
@@ -0,0 +1,101 @@ |
+// 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> |
+#include <queue> |
+#include <vector> |
+ |
+#include "base/macros.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/synchronization/lock.h" |
+#include "base/threading/thread.h" |
+#include "base/time/clock.h" |
+#include "base/timer/timer.h" |
+ |
+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: |
+ class AlarmDelegate { |
halliwell
2017/02/20 22:28:26
I wonder if it would be less intrusive for the cal
ryanchung
2017/02/21 23:36:47
Done.
I'm wondering if there's a need to explicitl
|
+ public: |
+ // Called when the alarm fires. |
+ virtual void OnAlarmFire() = 0; |
+ |
+ protected: |
+ virtual ~AlarmDelegate() {} |
+ }; |
+ |
+ // Construct and start the alarm manager. |
halliwell
2017/02/20 22:28:26
Is this intended to be some kind of singleton? Wh
ryanchung
2017/02/21 23:36:47
Yes, this will be some sort of singleton instantia
|
+ AlarmManager(); |
+ ~AlarmManager(); |
+ |
+ // For testing only. Allows setting a fake clock. |
+ AlarmManager(std::unique_ptr<base::Clock> clock); |
+ |
+ // Add an alarm. |
+ // OnAlarmFire() will be called on |delegate| at around |time|. |
+ void AddAlarm(AlarmDelegate* delegate, base::Time time); |
+ |
+ // Remove an alarm. |
+ void RemoveAlarm(AlarmDelegate* delegate); |
+ |
+ private: |
+ class AlarmInfo { |
+ public: |
+ AlarmInfo(base::Time time, |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
+ ~AlarmInfo(); |
+ base::Time time_; |
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(AlarmInfo); |
+ }; |
+ |
+ typedef std::map<AlarmDelegate*, std::unique_ptr<AlarmInfo>> AlarmMap; |
halliwell
2017/02/20 22:28:26
nit: 'using' preferred over typedef now.
ryanchung
2017/02/21 23:36:47
Done.
|
+ |
+ // Check if an alarm should fire. |
+ void CheckAlarm(); |
+ // Start the poller. |
+ void Start(); |
halliwell
2017/02/20 22:28:26
nit: seems like 'Start' code could be inlined in c
ryanchung
2017/02/21 23:36:47
Done.
|
+ // Stop the poller. |
+ void Stop(); |
halliwell
2017/02/20 22:28:26
nit: could inline this code in dtor.
ryanchung
2017/02/21 23:36:47
Done.
|
+ |
+ base::Lock alarms_lock_; |
halliwell
2017/02/20 22:28:26
Is there a strong reason to use a lock (vs posting
ryanchung
2017/02/21 23:36:47
Done. Posting is better. Updated code.
|
+ std::unique_ptr<base::Clock> clock_; |
+ std::unique_ptr<base::Timer> clock_tick_timer_; |
+ // Store a list of the alarms to fire at a certain time. |
+ AlarmMap alarms_; |
+ // Store a list of times when a timer should fire. |
+ std::priority_queue<base::Time, |
+ std::vector<base::Time>, |
+ std::greater<base::Time>> |
+ next_alarm_; |
+ |
+ base::WeakPtrFactory<AlarmManager> weak_factory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AlarmManager); |
+}; |
+ |
+} // chromecast |
halliwell
2017/02/20 22:28:26
nit: "namespace chromecast"
ryanchung
2017/02/21 23:36:46
Done.
|
+ |
+#endif // CHROMECAST_BASE_ALARM_MANAGER_H_ |