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 <list>
18 #include <memory>
19 #include <mutex>
20 #include <string_view>
21 #include <thread>
22 #include <unordered_map>
23 #include <unordered_set>
24 
25 #include "aemu/base/async/Looper.h"
26 
27 namespace android {
28 namespace base {
29 class SocketWaiter;
30 class Stream;
31 
32 // Default looper implementation based on select(). To make sure all timers and
33 // FD watches execute, run its runWithDeadlineMs() explicitly.
34 class DefaultLooper : public Looper {
35 public:
36     DefaultLooper();
37 
38     ~DefaultLooper() override;
39 
name()40     std::string_view name() const override { return "Generic"; }
41 
onLooperThread()42     bool onLooperThread() const override {
43         static thread_local std::thread::id thread_id = std::this_thread::get_id();
44         return mThreadId == thread_id;
45     }
46 
47     Duration nowMs(ClockType clockType = ClockType::kHost) override;
48 
49     DurationNs nowNs(ClockType clockType = ClockType::kHost) override;
50 
51     void forceQuit() override;
52 
53     //
54     //  F D   W A T C H E S
55     //
56     class FdWatch : public Looper::FdWatch {
57     public:
58         FdWatch(DefaultLooper* looper, int fd, Callback callback, void* opaque);
59 
60         DefaultLooper* defaultLooper() const;
61 
62         ~FdWatch() override;
63 
64         void addEvents(unsigned events) override;
65 
66         void removeEvents(unsigned events) override;
67 
68         unsigned poll() const override;
69 
70         // Return true iff this FdWatch is pending execution.
71         bool isPending() const;
72 
73         // Add this FdWatch to a pending queue.
74         void setPending(unsigned events);
75 
76         // Remove this FdWatch from a pending queue.
77         void clearPending();
78 
79         // Fire the watch, i.e. invoke the callback with the right
80         // parameters.
81         void fire();
82 
83     private:
84         unsigned mWantedEvents;
85         unsigned mLastEvents;
86         bool mPending;
87     };
88 
89     void addFdWatch(FdWatch* watch);
90 
91     void delFdWatch(FdWatch* watch);
92 
93     void addPendingFdWatch(FdWatch* watch);
94 
95     void delPendingFdWatch(FdWatch* watch);
96 
97     void updateFdWatch(int fd, unsigned wantedEvents);
98 
99     Looper::FdWatch* createFdWatch(int fd,
100                                    Looper::FdWatch::Callback callback,
101                                    void* opaque) override;
102 
103     //
104     //  T I M E R S
105     //
106 
107     class Timer : public Looper::Timer {
108     public:
109         Timer(DefaultLooper* looper,
110               Callback callback,
111               void* opaque,
112               ClockType clock);
113 
114         DefaultLooper* defaultLooper() const;
115 
116         ~Timer() override;
117 
118         Duration deadline() const;
119 
120         void startRelative(Duration deadlineMs) override;
121 
122         void startAbsolute(Duration deadlineMs) override;
123 
124         void stop() override;
125 
126         bool isActive() const override;
127 
128         void setPending();
129 
130         void clearPending();
131 
132         void fire();
133 
134         void save(Stream* stream) const override;
135 
136         void load(Stream* stream) override;
137 
138     private:
139         Duration mDeadline;
140         bool mPending;
141     };
142 
143     void addTimer(Timer* timer);
144 
145     void delTimer(Timer* timer);
146 
147     void enableTimer(Timer* timer);
148 
149     void disableTimer(Timer* timer);
150 
151     void addPendingTimer(Timer* timer);
152 
153     void delPendingTimer(Timer* timer);
154 
155     Looper::Timer* createTimer(Looper::Timer::Callback callback,
156                                void* opaque,
157                                ClockType clock) override;
158 
159     //
160     // Tasks
161     //
162     class Task : public Looper::Task {
163     public:
164         Task(Looper* looper, Looper::Task::Callback&& callback,
165              bool selfDeleting = false);
166 
167         ~Task();
168 
169         void schedule() override;
170         void cancel() override;
171         void run();
172 
173     private:
174         const bool mSelfDeleting;
175     };
176 
177     void addTask(Task* task);
178     void delTask(Task* task);
179 
180     TaskPtr createTask(TaskCallback&& callback) override;
181     void scheduleCallback(TaskCallback&& callback) override;
182 
183     //
184     //  M A I N   L O O P
185     //
186     int runWithDeadlineMs(Duration deadlineMs) override;
187 
188     typedef std::list<Timer*> TimerList;
189     typedef std::unordered_map<Timer*, TimerList::iterator> TimerSet;
190 
191     typedef std::list<FdWatch*> FdWatchList;
192     typedef std::unordered_map<FdWatch*, FdWatchList::iterator> FdWatchSet;
193 
194 protected:
195     bool runOneIterationWithDeadlineMs(Duration deadlineMs);
196 
197     std::unique_ptr<SocketWaiter> mWaiter;
198     FdWatchSet mFdWatches;          // Set of all fd watches.
199     FdWatchList mPendingFdWatches;  // Queue of pending fd watches.
200 
201     TimerSet mTimers;          // Set of all timers.
202     TimerList mActiveTimers;   // Sorted list of active timers.
203     TimerList mPendingTimers;  // Sorted list of pending timers.
204 
205     using TaskSet = std::unordered_set<Task*>;
206     TaskSet mScheduledTasks;
207     std::mutex mScheduledTasksAccess;
208 
209     bool mForcedExit = false;
210     std::thread::id mThreadId;
211 };
212 
213 }  // namespace base
214 }  // namespace android
215