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 */
32struct ALooper {
33};
34
35namespace android {
36
37/**
38 * 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 {
73protected:
74    virtual ~WeakMessageHandler();
75
76public:
77    WeakMessageHandler(const wp<MessageHandler>& handler);
78    virtual void handleMessage(const Message& message);
79
80private:
81    wp<MessageHandler> mHandler;
82};
83
84
85/**
86 * 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/**
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 */
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     */
174    int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
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);
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
322private:
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 {
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
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