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