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