blob: d4a0067fde609cedcca54e995198e0acf7fbf3a3 [file] [log] [blame]
Jeff Brown7901eb22010-09-13 23:17:30 -07001/*
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>
Jeff Brown8d15c742010-10-05 15:35:37 -070023#include <utils/Timers.h>
Jeff Brown7901eb22010-09-13 23:17:30 -070024
25#include <android/looper.h>
26
Jeff Brown8d15c742010-10-05 15:35:37 -070027#include <sys/epoll.h>
Jeff Brown8d15c742010-10-05 15:35:37 -070028
Jeff Brown7901eb22010-09-13 23:17:30 -070029/*
30 * Declare a concrete type for the NDK's looper forward declaration.
31 */
32struct ALooper {
33};
34
35namespace android {
36
37/**
Jeff Brown3e2e38b2011-03-02 14:41:58 -080038 * A message that can be posted to a Looper.
39 */
40struct Message {
41 Message() : what(0) { }
42 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 */
57class MessageHandler : public virtual RefBase {
58protected:
59 virtual ~MessageHandler() { }
60
61public:
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 */
72class WeakMessageHandler : public MessageHandler {
Jeff Browndd1b0372012-05-31 16:15:35 -070073protected:
74 virtual ~WeakMessageHandler();
75
Jeff Brown3e2e38b2011-03-02 14:41:58 -080076public:
77 WeakMessageHandler(const wp<MessageHandler>& handler);
78 virtual void handleMessage(const Message& message);
79
80private:
81 wp<MessageHandler> mHandler;
82};
83
84
85/**
Jeff Browndd1b0372012-05-31 16:15:35 -070086 * A looper callback.
87 */
88class LooperCallback : public virtual RefBase {
89protected:
90 virtual ~LooperCallback() { }
91
92public:
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 */
109class SimpleLooperCallback : public LooperCallback {
110protected:
111 virtual ~SimpleLooperCallback();
112
113public:
114 SimpleLooperCallback(ALooper_callbackFunc callback);
115 virtual int handleEvent(int fd, int events, void* data);
116
117private:
118 ALooper_callbackFunc mCallback;
119};
120
121
122/**
Jeff Brown7901eb22010-09-13 23:17:30 -0700123 * 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 */
128class Looper : public ALooper, public RefBase {
129protected:
130 virtual ~Looper();
131
132public:
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 */
Jeff Brown905682a2010-09-16 18:28:12 -0700174 int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
175 inline int pollOnce(int timeoutMillis) {
176 return pollOnce(timeoutMillis, NULL, NULL, NULL);
177 }
Jeff Brown7901eb22010-09-13 23:17:30 -0700178
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 */
Jeff Brown905682a2010-09-16 18:28:12 -0700184 int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
185 inline int pollAll(int timeoutMillis) {
186 return pollAll(timeoutMillis, NULL, NULL, NULL);
187 }
Jeff Brown7901eb22010-09-13 23:17:30 -0700188
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.
Jeff Browndd1b0372012-05-31 16:15:35 -0700202 * "ident" is an identifier for this event, which is returned from pollOnce().
Jeff Brown7901eb22010-09-13 23:17:30 -0700203 * 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.
Jeff Browndd1b0372012-05-31 16:15:35 -0700222 *
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.
Jeff Brown7901eb22010-09-13 23:17:30 -0700227 */
Jeff Brown905682a2010-09-16 18:28:12 -0700228 int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
Jeff Browndd1b0372012-05-31 16:15:35 -0700229 int addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data);
Jeff Brown7901eb22010-09-13 23:17:30 -0700230
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 *
Jeff Browndd1b0372012-05-31 16:15:35 -0700242 * 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 *
Jeff Brown7901eb22010-09-13 23:17:30 -0700246 * 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 /**
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800254 * 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 /**
Jeff Brown7901eb22010-09-13 23:17:30 -0700300 * 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
322private:
323 struct Request {
324 int fd;
325 int ident;
Jeff Browndd1b0372012-05-31 16:15:35 -0700326 sp<LooperCallback> callback;
Jeff Brown7901eb22010-09-13 23:17:30 -0700327 void* data;
328 };
329
330 struct Response {
331 int events;
332 Request request;
333 };
334
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800335 struct MessageEnvelope {
336 MessageEnvelope() : uptime(0) { }
337
338 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
Jeff Brown7901eb22010-09-13 23:17:30 -0700347 const bool mAllowNonCallbacks; // immutable
348
Jeff Brown7901eb22010-09-13 23:17:30 -0700349 int mWakeReadPipeFd; // immutable
350 int mWakeWritePipeFd; // immutable
Jeff Brown8d15c742010-10-05 15:35:37 -0700351 Mutex mLock;
352
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800353 Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
354 bool mSendingMessage; // guarded by mLock
355
Jeff Brown8d15c742010-10-05 15:35:37 -0700356 int mEpollFd; // immutable
Jeff Brown7901eb22010-09-13 23:17:30 -0700357
358 // Locked list of file descriptor monitoring requests.
Jeff Brown8d15c742010-10-05 15:35:37 -0700359 KeyedVector<int, Request> mRequests; // guarded by mLock
Jeff Brown8d15c742010-10-05 15:35:37 -0700360
Jeff Brown7901eb22010-09-13 23:17:30 -0700361 // 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;
Jeff Brown3e2e38b2011-03-02 14:41:58 -0800365 nsecs_t mNextMessageUptime; // set to LLONG_MAX when none
Jeff Brown7901eb22010-09-13 23:17:30 -0700366
367 int pollInner(int timeoutMillis);
Jeff Brown8d15c742010-10-05 15:35:37 -0700368 void awoken();
369 void pushResponse(int events, const Request& request);
Jeff Brown7901eb22010-09-13 23:17:30 -0700370
Jeff Brownd1805182010-09-21 15:11:18 -0700371 static void initTLSKey();
Jeff Brown7901eb22010-09-13 23:17:30 -0700372 static void threadDestructor(void *st);
373};
374
375} // namespace android
376
377#endif // UTILS_LOOPER_H