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     // True if the current thread is a looper thread.
69     virtual bool onLooperThread() const = 0;
70 
71     // Return the current time as seen by this looper instance in
72     // milliseconds and nanoseconds.
73     virtual Duration nowMs(ClockType clockType = ClockType::kHost) = 0;
74     virtual DurationNs nowNs(ClockType clockType = ClockType::kHost) = 0;
75 
76     // Run the event loop until forceQuit() is called or there is no
77     // more registered watchers or timers in the looper.
78     void run();
79 
80     // A variant of run() that allows to run the event loop only until
81     // a fixed deadline has passed. |deadlineMs| is a deadline in
82     // milliseconds relative to the current clock used by nowMs().
83     // If can be kDurationInfinite to indicate no deadline.
84     // Return the reason why the looper stopped:
85     //    0           -> normal exit through forceQuit()
86     //    EWOULDBLOCK -> no more watchers and timers registered.
87     //    ETIMEOUT    -> timeout reached.
88     virtual int runWithDeadlineMs(Duration deadlineMs) = 0;
89 
90     // A variant of run() that allows to run the event loop only until
91     // a certain timeout is milliseconds has passed. Return the reason
92     // why the looper stopped:
93     //    0           -> normal exit through forceQuit()
94     //    EWOULDBLOCK -> no more watchers and timers registered.
95     //    ETIMEOUT    -> timeout reached.
96     int runWithTimeoutMs(Duration timeoutMs);
97 
98     // Call this function from within the event loop to force it to quit
99     // as soon as possible. runWithDeadlineMS() and runWithTimeoutMs() will
100     // return 0.
101     virtual void forceQuit() = 0;
102 
103     // Interface class for timers implemented by a Looper instance.
104     // Use createTimer() to create these.
105     class Timer {
106     public:
107         // Type of callback function called when the timer expires.
108         typedef void (*Callback)(void* opaque, Timer* timer);
109 
110         virtual ~Timer();
111 
112         // Get the parent looper object
113         Looper* parentLooper() const;
114 
115         // Start, or restart the timer to expire after |timeout_ms|
116         // milliseconds.
117         virtual void startRelative(Duration timeout_ms) = 0;
118 
119         // Start, or restart the timer to expire at |deadline_ms|
120         // milliseconds.
121         virtual void startAbsolute(Duration deadline_ms) = 0;
122 
123         // Stop the timer.
124         virtual void stop() = 0;
125 
126         // Returns true iff this timer is active.
127         virtual bool isActive() const = 0;
128 
129         // Serialization to/from streams
130         virtual void save(android::base::Stream* stream) const = 0;
131         virtual void load(android::base::Stream* stream) = 0;
132 
133     protected:
134         Timer(Looper* looper, Callback callback, void* opaque,
135               ClockType clock);
136 
137         Looper* mLooper;
138         Callback mCallback;
139         void* mOpaque;
140         ClockType mClockType;
141     };
142 
143     // Create a new timer for this Looper instance.
144     virtual Timer* createTimer(Timer::Callback callback, void* opaque,
145                                ClockType clock = ClockType::kHost) = 0;
146 
147     // Interface class for I/O event watchers on a given file descriptor
148     // implemented by this Looper instance.
149     class FdWatch {
150     public:
151         enum {
152             kEventRead = (1 << 0),
153             kEventWrite = (1 << 1),
154 
155             kEventMask = (kEventRead | kEventWrite),
156         };
157 
158         // Type of function called when an I/O event occurs.
159         // |opaque| is the opaque pointer passed at creation.
160         // |fd| is the file descriptor.
161         // |events| is an event bitmask.
162         typedef void (*Callback)(void* opaque, int fd, unsigned events);
163 
164         virtual ~FdWatch();
165 
166         virtual void addEvents(unsigned events) = 0;
167 
168         virtual void removeEvents(unsigned events) = 0;
169 
wantRead()170         inline void wantRead() {
171             addEvents(FdWatch::kEventRead);
172         }
wantWrite()173         inline void wantWrite() {
174             addEvents(FdWatch::kEventWrite);
175         }
dontWantRead()176         inline void dontWantRead() {
177             removeEvents(FdWatch::kEventRead);
178         }
dontWantWrite()179         inline void dontWantWrite() {
180             removeEvents(FdWatch::kEventWrite);
181         }
182 
183         virtual unsigned poll() const = 0;
184 
185         int fd() const;
186 
187     protected:
188         FdWatch(Looper* looper, int fd, Callback callback, void* opaque);
189 
190         Looper* mLooper;
191         int mFd;
192         Callback mCallback;
193         void* mOpaque;
194     };
195 
196     // Create a new FdWatch instance from this looper.
197     virtual FdWatch* createFdWatch(int fd,
198                                    FdWatch::Callback callback,
199                                    void* opaque) = 0;
200 
201     // An interface for running a task on the main looper thread with as little
202     // delay as possible.
203     class Task {
204         DISALLOW_COPY_AND_ASSIGN(Task);
205 
206     public:
207         using Callback = std::function<void()>;
208 
209         virtual ~Task();
210 
211         // Schedule this task to run on the main looper thread. It will only run
212         // once, call schedule() again after that if you need to run it again.
213         virtual void schedule() = 0;
214 
215         // Cancel the scheduled task. It's OK to call it if the task isn't
216         // scheduled.
217         virtual void cancel() = 0;
218 
219     protected:
220         Task(Looper* looper, Callback&& callback);
221 
222         Looper* const mLooper;
223         const Callback mCallback;
224     };
225 
226     using TaskPtr = std::unique_ptr<Task>;
227     using TaskCallback = Task::Callback;
228 
229     // Creates a new Task instance for this looper.
230     virtual TaskPtr createTask(TaskCallback&& callback) = 0;
231 
232     // Schedules the specified one-shot |callback| to run on the main looper
233     // thread and returns (doesn't wait for task to complete).
234     virtual void scheduleCallback(TaskCallback&& callback) = 0;
235 
236 protected:
237     // Default constructor is protected. Use create() method to create
238     // new generic Looper instances.
239     Looper();
240 
241 private:
242     DISALLOW_COPY_AND_ASSIGN(Looper);
243 };
244 
245 }  // namespace base
246 }  // namespace android
247