1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <thread>
22 
23 #include <android-base/thread_annotations.h>
24 
25 namespace android {
26 namespace scheduler {
27 
28 /*
29  * Class that sets off a timer for a given interval, and fires a callback when the
30  * interval expires.
31  */
32 class OneShotTimer {
33 public:
34     using Interval = std::chrono::milliseconds;
35     using ResetCallback = std::function<void()>;
36     using TimeoutCallback = std::function<void()>;
37 
38     OneShotTimer(const Interval& interval, const ResetCallback& resetCallback,
39                  const TimeoutCallback& timeoutCallback);
40     ~OneShotTimer();
41 
42     // Initializes and turns on the idle timer.
43     void start();
44     // Stops the idle timer and any held resources.
45     void stop();
46     // Resets the wakeup time and fires the reset callback.
47     void reset();
48 
49     std::string dump() const;
50 
51 private:
52     // Enum to track in what state is the timer.
53     enum class TimerState {
54         // The internal timer thread has been destroyed, and no state is
55         // tracked.
56         // Possible state transitions: RESET
57         STOPPED = 0,
58         // An external thread has just reset this timer.
59         // If there is a reset callback, then that callback is fired.
60         // Possible state transitions: STOPPED, WAITING
61         RESET = 1,
62         // This timer is waiting for the timeout interval to expire.
63         // Possible state transaitions: STOPPED, RESET, IDLE
64         WAITING = 2,
65         // The timeout interval has expired, so we are sleeping now.
66         // Possible state transaitions: STOPPED, RESET
67         IDLE = 3
68     };
69 
70     // Function that loops until the condition for stopping is met.
71     void loop();
72 
73     // Thread waiting for timer to expire.
74     std::thread mThread;
75 
76     // Condition used to notify mThread.
77     std::condition_variable_any mCondition;
78 
79     // Lock used for synchronizing the waiting thread with the application thread.
80     std::mutex mMutex;
81 
82     // Current timer state
83     TimerState mState GUARDED_BY(mMutex) = TimerState::RESET;
84 
85     // Interval after which timer expires.
86     const Interval mInterval;
87 
88     // Callback that happens when timer resets.
89     const ResetCallback mResetCallback;
90 
91     // Callback that happens when timer expires.
92     const TimeoutCallback mTimeoutCallback;
93 };
94 
95 } // namespace scheduler
96 } // namespace android
97