• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #ifndef UTILS_LOOPER_H
18 #define UTILS_LOOPER_H
19 
20 #include <utils/threads.h>
21 #include <utils/RefBase.h>
22 #include <utils/KeyedVector.h>
23 #include <utils/Timers.h>
24 
25 #include <android/looper.h>
26 
27 #include <sys/epoll.h>
28 
29 /*
30  * Declare a concrete type for the NDK's looper forward declaration.
31  */
32 struct ALooper {
33 };
34 
35 namespace android {
36 
37 /**
38  * A message that can be posted to a Looper.
39  */
40 struct Message {
MessageMessage41     Message() : what(0) { }
MessageMessage42     Message(int what) : what(what) { }
43 
44     /* The message type. (interpretation is left up to the handler) */
45     int what;
46 };
47 
48 
49 /**
50  * Interface for a Looper message handler.
51  *
52  * The Looper holds a strong reference to the message handler whenever it has
53  * a message to deliver to it.  Make sure to call Looper::removeMessages
54  * to remove any pending messages destined for the handler so that the handler
55  * can be destroyed.
56  */
57 class MessageHandler : public virtual RefBase {
58 protected:
~MessageHandler()59     virtual ~MessageHandler() { }
60 
61 public:
62     /**
63      * Handles a message.
64      */
65     virtual void handleMessage(const Message& message) = 0;
66 };
67 
68 
69 /**
70  * A simple proxy that holds a weak reference to a message handler.
71  */
72 class WeakMessageHandler : public MessageHandler {
73 protected:
74     virtual ~WeakMessageHandler();
75 
76 public:
77     WeakMessageHandler(const wp<MessageHandler>& handler);
78     virtual void handleMessage(const Message& message);
79 
80 private:
81     wp<MessageHandler> mHandler;
82 };
83 
84 
85 /**
86  * A looper callback.
87  */
88 class LooperCallback : public virtual RefBase {
89 protected:
~LooperCallback()90     virtual ~LooperCallback() { }
91 
92 public:
93     /**
94      * Handles a poll event for the given file descriptor.
95      * It is given the file descriptor it is associated with,
96      * a bitmask of the poll events that were triggered (typically ALOOPER_EVENT_INPUT),
97      * and the data pointer that was originally supplied.
98      *
99      * Implementations should return 1 to continue receiving callbacks, or 0
100      * to have this file descriptor and callback unregistered from the looper.
101      */
102     virtual int handleEvent(int fd, int events, void* data) = 0;
103 };
104 
105 
106 /**
107  * Wraps a ALooper_callbackFunc function pointer.
108  */
109 class SimpleLooperCallback : public LooperCallback {
110 protected:
111     virtual ~SimpleLooperCallback();
112 
113 public:
114     SimpleLooperCallback(ALooper_callbackFunc callback);
115     virtual int handleEvent(int fd, int events, void* data);
116 
117 private:
118     ALooper_callbackFunc mCallback;
119 };
120 
121 
122 /**
123  * A polling loop that supports monitoring file descriptor events, optionally
124  * using callbacks.  The implementation uses epoll() internally.
125  *
126  * A looper can be associated with a thread although there is no requirement that it must be.
127  */
128 class Looper : public ALooper, public RefBase {
129 protected:
130     virtual ~Looper();
131 
132 public:
133     /**
134      * Creates a looper.
135      *
136      * If allowNonCallbaks is true, the looper will allow file descriptors to be
137      * registered without associated callbacks.  This assumes that the caller of
138      * pollOnce() is prepared to handle callback-less events itself.
139      */
140     Looper(bool allowNonCallbacks);
141 
142     /**
143      * Returns whether this looper instance allows the registration of file descriptors
144      * using identifiers instead of callbacks.
145      */
146     bool getAllowNonCallbacks() const;
147 
148     /**
149      * Waits for events to be available, with optional timeout in milliseconds.
150      * Invokes callbacks for all file descriptors on which an event occurred.
151      *
152      * If the timeout is zero, returns immediately without blocking.
153      * If the timeout is negative, waits indefinitely until an event appears.
154      *
155      * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
156      * the timeout expired and no callbacks were invoked and no other file
157      * descriptors were ready.
158      *
159      * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
160      *
161      * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
162      * timeout expired.
163      *
164      * Returns ALOOPER_POLL_ERROR if an error occurred.
165      *
166      * Returns a value >= 0 containing an identifier if its file descriptor has data
167      * and it has no callback function (requiring the caller here to handle it).
168      * In this (and only this) case outFd, outEvents and outData will contain the poll
169      * events and data associated with the fd, otherwise they will be set to NULL.
170      *
171      * This method does not return until it has finished invoking the appropriate callbacks
172      * for all file descriptors that were signalled.
173      */
174     int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
pollOnce(int timeoutMillis)175     inline int pollOnce(int timeoutMillis) {
176         return pollOnce(timeoutMillis, NULL, NULL, NULL);
177     }
178 
179     /**
180      * Like pollOnce(), but performs all pending callbacks until all
181      * data has been consumed or a file descriptor is available with no callback.
182      * This function will never return ALOOPER_POLL_CALLBACK.
183      */
184     int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
pollAll(int timeoutMillis)185     inline int pollAll(int timeoutMillis) {
186         return pollAll(timeoutMillis, NULL, NULL, NULL);
187     }
188 
189     /**
190      * Wakes the poll asynchronously.
191      *
192      * This method can be called on any thread.
193      * This method returns immediately.
194      */
195     void wake();
196 
197     /**
198      * Adds a new file descriptor to be polled by the looper.
199      * If the same file descriptor was previously added, it is replaced.
200      *
201      * "fd" is the file descriptor to be added.
202      * "ident" is an identifier for this event, which is returned from pollOnce().
203      * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
204      * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
205      * "callback" is the function to call when there is an event on the file descriptor.
206      * "data" is a private data pointer to supply to the callback.
207      *
208      * There are two main uses of this function:
209      *
210      * (1) If "callback" is non-NULL, then this function will be called when there is
211      * data on the file descriptor.  It should execute any events it has pending,
212      * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
213      *
214      * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
215      * when its file descriptor has data available, requiring the caller to take
216      * care of processing it.
217      *
218      * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
219      *
220      * This method can be called on any thread.
221      * This method may block briefly if it needs to wake the poll.
222      *
223      * The callback may either be specified as a bare function pointer or as a smart
224      * pointer callback object.  The smart pointer should be preferred because it is
225      * easier to avoid races when the callback is removed from a different thread.
226      * See removeFd() for details.
227      */
228     int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
229     int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);
230 
231     /**
232      * Removes a previously added file descriptor from the looper.
233      *
234      * When this method returns, it is safe to close the file descriptor since the looper
235      * will no longer have a reference to it.  However, it is possible for the callback to
236      * already be running or for it to run one last time if the file descriptor was already
237      * signalled.  Calling code is responsible for ensuring that this case is safely handled.
238      * For example, if the callback takes care of removing itself during its own execution either
239      * by returning 0 or by calling this method, then it can be guaranteed to not be invoked
240      * again at any later time unless registered anew.
241      *
242      * A simple way to avoid this problem is to use the version of addFd() that takes
243      * a sp<LooperCallback> instead of a bare function pointer.  The LooperCallback will
244      * be released at the appropriate time by the Looper.
245      *
246      * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
247      *
248      * This method can be called on any thread.
249      * This method may block briefly if it needs to wake the poll.
250      */
251     int removeFd(int fd);
252 
253     /**
254      * Enqueues a message to be processed by the specified handler.
255      *
256      * The handler must not be null.
257      * This method can be called on any thread.
258      */
259     void sendMessage(const sp<MessageHandler>& handler, const Message& message);
260 
261     /**
262      * Enqueues a message to be processed by the specified handler after all pending messages
263      * after the specified delay.
264      *
265      * The time delay is specified in uptime nanoseconds.
266      * The handler must not be null.
267      * This method can be called on any thread.
268      */
269     void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
270             const Message& message);
271 
272     /**
273      * Enqueues a message to be processed by the specified handler after all pending messages
274      * at the specified time.
275      *
276      * The time is specified in uptime nanoseconds.
277      * The handler must not be null.
278      * This method can be called on any thread.
279      */
280     void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
281             const Message& message);
282 
283     /**
284      * Removes all messages for the specified handler from the queue.
285      *
286      * The handler must not be null.
287      * This method can be called on any thread.
288      */
289     void removeMessages(const sp<MessageHandler>& handler);
290 
291     /**
292      * Removes all messages of a particular type for the specified handler from the queue.
293      *
294      * The handler must not be null.
295      * This method can be called on any thread.
296      */
297     void removeMessages(const sp<MessageHandler>& handler, int what);
298 
299     /**
300      * Prepares a looper associated with the calling thread, and returns it.
301      * If the thread already has a looper, it is returned.  Otherwise, a new
302      * one is created, associated with the thread, and returned.
303      *
304      * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
305      */
306     static sp<Looper> prepare(int opts);
307 
308     /**
309      * Sets the given looper to be associated with the calling thread.
310      * If another looper is already associated with the thread, it is replaced.
311      *
312      * If "looper" is NULL, removes the currently associated looper.
313      */
314     static void setForThread(const sp<Looper>& looper);
315 
316     /**
317      * Returns the looper associated with the calling thread, or NULL if
318      * there is not one.
319      */
320     static sp<Looper> getForThread();
321 
322 private:
323     struct Request {
324         int fd;
325         int ident;
326         sp<LooperCallback> callback;
327         void* data;
328     };
329 
330     struct Response {
331         int events;
332         Request request;
333     };
334 
335     struct MessageEnvelope {
MessageEnvelopeMessageEnvelope336         MessageEnvelope() : uptime(0) { }
337 
MessageEnvelopeMessageEnvelope338         MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
339                 const Message& message) : uptime(uptime), handler(handler), message(message) {
340         }
341 
342         nsecs_t uptime;
343         sp<MessageHandler> handler;
344         Message message;
345     };
346 
347     const bool mAllowNonCallbacks; // immutable
348 
349     int mWakeReadPipeFd;  // immutable
350     int mWakeWritePipeFd; // immutable
351     Mutex mLock;
352 
353     Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
354     bool mSendingMessage; // guarded by mLock
355 
356     int mEpollFd; // immutable
357 
358     // Locked list of file descriptor monitoring requests.
359     KeyedVector<int, Request> mRequests;  // guarded by mLock
360 
361     // This state is only used privately by pollOnce and does not require a lock since
362     // it runs on a single thread.
363     Vector<Response> mResponses;
364     size_t mResponseIndex;
365     nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
366 
367     int pollInner(int timeoutMillis);
368     void awoken();
369     void pushResponse(int events, const Request& request);
370 
371     static void initTLSKey();
372     static void threadDestructor(void *st);
373 };
374 
375 } // namespace android
376 
377 #endif // UTILS_LOOPER_H
378