2 * Copyright (C) 2010 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef UTILS_LOOPER_H
18 #define UTILS_LOOPER_H
20 #include <utils/threads.h>
21 #include <utils/RefBase.h>
22 #include <utils/KeyedVector.h>
23 #include <utils/Timers.h>
25 #include <android/looper.h>
27 #include <sys/epoll.h>
30 * Declare a concrete type for the NDK's looper forward declaration.
38 * A message that can be posted to a Looper.
41 Message() : what(0) { }
42 Message(int what) : what(what) { }
44 /* The message type. (interpretation is left up to the handler) */
50 * Interface for a Looper message handler.
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
57 class MessageHandler : public virtual RefBase {
59 virtual ~MessageHandler() { }
65 virtual void handleMessage(const Message& message) = 0;
70 * A simple proxy that holds a weak reference to a message handler.
72 class WeakMessageHandler : public MessageHandler {
74 virtual ~WeakMessageHandler();
77 WeakMessageHandler(const wp<MessageHandler>& handler);
78 virtual void handleMessage(const Message& message);
81 wp<MessageHandler> mHandler;
88 class LooperCallback : public virtual RefBase {
90 virtual ~LooperCallback() { }
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.
99 * Implementations should return 1 to continue receiving callbacks, or 0
100 * to have this file descriptor and callback unregistered from the looper.
102 virtual int handleEvent(int fd, int events, void* data) = 0;
107 * Wraps a ALooper_callbackFunc function pointer.
109 class SimpleLooperCallback : public LooperCallback {
111 virtual ~SimpleLooperCallback();
114 SimpleLooperCallback(ALooper_callbackFunc callback);
115 virtual int handleEvent(int fd, int events, void* data);
118 ALooper_callbackFunc mCallback;
123 * A polling loop that supports monitoring file descriptor events, optionally
124 * using callbacks. The implementation uses epoll() internally.
126 * A looper can be associated with a thread although there is no requirement that it must be.
128 class Looper : public ALooper, public RefBase {
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.
140 Looper(bool allowNonCallbacks);
143 * Returns whether this looper instance allows the registration of file descriptors
144 * using identifiers instead of callbacks.
146 bool getAllowNonCallbacks() const;
149 * Waits for events to be available, with optional timeout in milliseconds.
150 * Invokes callbacks for all file descriptors on which an event occurred.
152 * If the timeout is zero, returns immediately without blocking.
153 * If the timeout is negative, waits indefinitely until an event appears.
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.
159 * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
161 * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
164 * Returns ALOOPER_POLL_ERROR if an error occurred.
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.
171 * This method does not return until it has finished invoking the appropriate callbacks
172 * for all file descriptors that were signalled.
174 int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
175 inline int pollOnce(int timeoutMillis) {
176 return pollOnce(timeoutMillis, NULL, NULL, NULL);
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.
184 int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
185 inline int pollAll(int timeoutMillis) {
186 return pollAll(timeoutMillis, NULL, NULL, NULL);
190 * Wakes the poll asynchronously.
192 * This method can be called on any thread.
193 * This method returns immediately.
198 * Adds a new file descriptor to be polled by the looper.
199 * If the same file descriptor was previously added, it is replaced.
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.
208 * There are two main uses of this function:
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.
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.
218 * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
220 * This method can be called on any thread.
221 * This method may block briefly if it needs to wake the poll.
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.
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);
232 * Removes a previously added file descriptor from the looper.
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.
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.
246 * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
248 * This method can be called on any thread.
249 * This method may block briefly if it needs to wake the poll.
251 int removeFd(int fd);
254 * Enqueues a message to be processed by the specified handler.
256 * The handler must not be null.
257 * This method can be called on any thread.
259 void sendMessage(const sp<MessageHandler>& handler, const Message& message);
262 * Enqueues a message to be processed by the specified handler after all pending messages
263 * after the specified delay.
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.
269 void sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
270 const Message& message);
273 * Enqueues a message to be processed by the specified handler after all pending messages
274 * at the specified time.
276 * The time is specified in uptime nanoseconds.
277 * The handler must not be null.
278 * This method can be called on any thread.
280 void sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
281 const Message& message);
284 * Removes all messages for the specified handler from the queue.
286 * The handler must not be null.
287 * This method can be called on any thread.
289 void removeMessages(const sp<MessageHandler>& handler);
292 * Removes all messages of a particular type for the specified handler from the queue.
294 * The handler must not be null.
295 * This method can be called on any thread.
297 void removeMessages(const sp<MessageHandler>& handler, int what);
300 * Return whether this looper's thread is currently idling -- that is, whether it
301 * stopped waiting for more work to do. Note that this is intrinsically racy, since
302 * its state can change before you get the result back.
304 bool isIdling() const;
307 * Prepares a looper associated with the calling thread, and returns it.
308 * If the thread already has a looper, it is returned. Otherwise, a new
309 * one is created, associated with the thread, and returned.
311 * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
313 static sp<Looper> prepare(int opts);
316 * Sets the given looper to be associated with the calling thread.
317 * If another looper is already associated with the thread, it is replaced.
319 * If "looper" is NULL, removes the currently associated looper.
321 static void setForThread(const sp<Looper>& looper);
324 * Returns the looper associated with the calling thread, or NULL if
327 static sp<Looper> getForThread();
333 sp<LooperCallback> callback;
342 struct MessageEnvelope {
343 MessageEnvelope() : uptime(0) { }
345 MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
346 const Message& message) : uptime(uptime), handler(handler), message(message) {
350 sp<MessageHandler> handler;
354 const bool mAllowNonCallbacks; // immutable
356 int mWakeReadPipeFd; // immutable
357 int mWakeWritePipeFd; // immutable
360 Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
361 bool mSendingMessage; // guarded by mLock
363 // Whether we are currently waiting for work. Not protected by a lock,
364 // any use of it is racy anyway.
365 volatile bool mIdling;
367 int mEpollFd; // immutable
369 // Locked list of file descriptor monitoring requests.
370 KeyedVector<int, Request> mRequests; // guarded by mLock
372 // This state is only used privately by pollOnce and does not require a lock since
373 // it runs on a single thread.
374 Vector<Response> mResponses;
375 size_t mResponseIndex;
376 nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
378 int pollInner(int timeoutMillis);
380 void pushResponse(int events, const Request& request);
382 static void initTLSKey();
383 static void threadDestructor(void *st);
386 } // namespace android
388 #endif // UTILS_LOOPER_H