1 // Copyright 2014 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include <aemu/base/Compiler.h>
18 #include <aemu/base/files/Stream.h>
19 
20 #include <functional>
21 #include <memory>
22 #include <string_view>
23 #include <utility>
24 
25 #include <inttypes.h>
26 #include <stddef.h>
27 #include <stdint.h>
28 
29 namespace android {
30 namespace base {
31 
32 // A Looper is an abstraction for an event loop that can wait for either
33 // I/O events on file descriptors, or timers.
34 //
35 // One can call Looper::create() to create a new instance, create
36 // Looper::Timer and Looper::FdWatch instances, then call Looper::run()
37 // to run the loop until there is nothing more to do.
38 //
39 // It's possible to stop a Looper from running by calling
40 // Looper::forceQuit() from within the event loop.
41 //
42 class Looper {
43 public:
44     typedef int64_t Duration;
45     typedef uint64_t DurationNs;
46 
47     enum Timeout : int64_t {
48         kDurationInfinite = INT64_MAX,
49     };
50 
51     // ClockTypes have to mimic the LooperClockType enum from utils/
52     enum class ClockType {
53         kRealtime,
54         kVirtual,
55         kHost
56     };
57 
58     static const char* clockTypeToString(ClockType clock);
59 
60     // Create a new generic Looper instance.
61     static Looper* create();
62 
63     virtual ~Looper();
64 
65     // Return the current looper's name - useful for logging.
66     virtual std::string_view name() const = 0;
67 
68     // Return the current time as seen by this looper instance in
69     // milliseconds and nanoseconds.
70     virtual Duration nowMs(ClockType clockType = ClockType::kHost) = 0;
71     virtual DurationNs nowNs(ClockType clockType = ClockType::kHost) = 0;
72 
73     // Run the event loop until forceQuit() is called or there is no
74     // more registered watchers or timers in the looper.
75     void run();
76 
77     // A variant of run() that allows to run the event loop only until
78     // a fixed deadline has passed. |deadlineMs| is a deadline in
79     // milliseconds relative to the current clock used by nowMs().
80     // If can be kDurationInfinite to indicate no deadline.
81     // Return the reason why the looper stopped:
82     //    0           -> normal exit through forceQuit()
83     //    EWOULDBLOCK -> no more watchers and timers registered.
84     //    ETIMEOUT    -> timeout reached.
85     virtual int runWithDeadlineMs(Duration deadlineMs) = 0;
86 
87     // A variant of run() that allows to run the event loop only until
88     // a certain timeout is milliseconds has passed. Return the reason
89     // why the looper stopped:
90     //    0           -> normal exit through forceQuit()
91     //    EWOULDBLOCK -> no more watchers and timers registered.
92     //    ETIMEOUT    -> timeout reached.
93     int runWithTimeoutMs(Duration timeoutMs);
94 
95     // Call this function from within the event loop to force it to quit
96     // as soon as possible. runWithDeadlineMS() and runWithTimeoutMs() will
97     // return 0.
98     virtual void forceQuit() = 0;
99 
100     // Interface class for timers implemented by a Looper instance.
101     // Use createTimer() to create these.
102     class Timer {
103     public:
104         // Type of callback function called when the timer expires.
105         typedef void (*Callback)(void* opaque, Timer* timer);
106 
107         virtual ~Timer();
108 
109         // Get the parent looper object
110         Looper* parentLooper() const;
111 
112         // Start, or restart the timer to expire after |timeout_ms|
113         // milliseconds.
114         virtual void startRelative(Duration timeout_ms) = 0;
115 
116         // Start, or restart the timer to expire at |deadline_ms|
117         // milliseconds.
118         virtual void startAbsolute(Duration deadline_ms) = 0;
119 
120         // Stop the timer.
121         virtual void stop() = 0;
122 
123         // Returns true iff this timer is active.
124         virtual bool isActive() const = 0;
125 
126         // Serialization to/from streams
127         virtual void save(android::base::Stream* stream) const = 0;
128         virtual void load(android::base::Stream* stream) = 0;
129 
130     protected:
131         Timer(Looper* looper, Callback callback, void* opaque,
132               ClockType clock);
133 
134         Looper* mLooper;
135         Callback mCallback;
136         void* mOpaque;
137         ClockType mClockType;
138     };
139 
140     // Create a new timer for this Looper instance.
141     virtual Timer* createTimer(Timer::Callback callback, void* opaque,
142                                ClockType clock = ClockType::kHost) = 0;
143 
144     // Interface class for I/O event watchers on a given file descriptor
145     // implemented by this Looper instance.
146     class FdWatch {
147     public:
148         enum {
149             kEventRead = (1 << 0),
150             kEventWrite = (1 << 1),
151 
152             kEventMask = (kEventRead | kEventWrite),
153         };
154 
155         // Type of function called when an I/O event occurs.
156         // |opaque| is the opaque pointer passed at creation.
157         // |fd| is the file descriptor.
158         // |events| is an event bitmask.
159         typedef void (*Callback)(void* opaque, int fd, unsigned events);
160 
161         virtual ~FdWatch();
162 
163         virtual void addEvents(unsigned events) = 0;
164 
165         virtual void removeEvents(unsigned events) = 0;
166 
wantRead()167         inline void wantRead() {
168             addEvents(FdWatch::kEventRead);
169         }
wantWrite()170         inline void wantWrite() {
171             addEvents(FdWatch::kEventWrite);
172         }
dontWantRead()173         inline void dontWantRead() {
174             removeEvents(FdWatch::kEventRead);
175         }
dontWantWrite()176         inline void dontWantWrite() {
177             removeEvents(FdWatch::kEventWrite);
178         }
179 
180         virtual unsigned poll() const = 0;
181 
182         int fd() const;
183 
184     protected:
185         FdWatch(Looper* looper, int fd, Callback callback, void* opaque);
186 
187         Looper* mLooper;
188         int mFd;
189         Callback mCallback;
190         void* mOpaque;
191     };
192 
193     // Create a new FdWatch instance from this looper.
194     virtual FdWatch* createFdWatch(int fd,
195                                    FdWatch::Callback callback,
196                                    void* opaque) = 0;
197 
198     // An interface for running a task on the main looper thread with as little
199     // delay as possible.
200     class Task {
201         DISALLOW_COPY_AND_ASSIGN(Task);
202 
203     public:
204         using Callback = std::function<void()>;
205 
206         virtual ~Task();
207 
208         // Schedule this task to run on the main looper thread. It will only run
209         // once, call schedule() again after that if you need to run it again.
210         virtual void schedule() = 0;
211 
212         // Cancel the scheduled task. It's OK to call it if the task isn't
213         // scheduled.
214         virtual void cancel() = 0;
215 
216     protected:
217         Task(Looper* looper, Callback&& callback);
218 
219         Looper* const mLooper;
220         const Callback mCallback;
221     };
222 
223     using TaskPtr = std::unique_ptr<Task>;
224     using TaskCallback = Task::Callback;
225 
226     // Creates a new Task instance for this looper.
227     virtual TaskPtr createTask(TaskCallback&& callback) = 0;
228 
229     // Schedules the specified one-shot |callback| to run on the main looper
230     // thread and returns (doesn't wait for task to complete).
231     virtual void scheduleCallback(TaskCallback&& callback) = 0;
232 
233 protected:
234     // Default constructor is protected. Use create() method to create
235     // new generic Looper instances.
236     Looper();
237 
238 private:
239     DISALLOW_COPY_AND_ASSIGN(Looper);
240 };
241 
242 }  // namespace base
243 }  // namespace android
244