OSDN Git Service

Merge "add static dependency on liblog"
[android-x86/frameworks-native.git] / include / utils / Looper.h
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  */
32 struct ALooper {
33 };
34
35 namespace android {
36
37 /**
38  * A message that can be posted to a Looper.
39  */
40 struct 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  */
57 class MessageHandler : public virtual RefBase {
58 protected:
59     virtual ~MessageHandler() { }
60
61 public:
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  */
72 class WeakMessageHandler : public MessageHandler {
73 protected:
74     virtual ~WeakMessageHandler();
75
76 public:
77     WeakMessageHandler(const wp<MessageHandler>& handler);
78     virtual void handleMessage(const Message& message);
79
80 private:
81     wp<MessageHandler> mHandler;
82 };
83
84
85 /**
86  * A looper callback.
87  */
88 class LooperCallback : public virtual RefBase {
89 protected:
90     virtual ~LooperCallback() { }
91
92 public:
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  */
109 class SimpleLooperCallback : public LooperCallback {
110 protected:
111     virtual ~SimpleLooperCallback();
112
113 public:
114     SimpleLooperCallback(ALooper_callbackFunc callback);
115     virtual int handleEvent(int fd, int events, void* data);
116
117 private:
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  */
128 class Looper : public ALooper, public RefBase {
129 protected:
130     virtual ~Looper();
131
132 public:
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      * 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.
303      */
304     bool isIdling() const;
305
306     /**
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.
310      *
311      * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
312      */
313     static sp<Looper> prepare(int opts);
314
315     /**
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.
318      *
319      * If "looper" is NULL, removes the currently associated looper.
320      */
321     static void setForThread(const sp<Looper>& looper);
322
323     /**
324      * Returns the looper associated with the calling thread, or NULL if
325      * there is not one.
326      */
327     static sp<Looper> getForThread();
328
329 private:
330     struct Request {
331         int fd;
332         int ident;
333         sp<LooperCallback> callback;
334         void* data;
335     };
336
337     struct Response {
338         int events;
339         Request request;
340     };
341
342     struct MessageEnvelope {
343         MessageEnvelope() : uptime(0) { }
344
345         MessageEnvelope(nsecs_t uptime, const sp<MessageHandler> handler,
346                 const Message& message) : uptime(uptime), handler(handler), message(message) {
347         }
348
349         nsecs_t uptime;
350         sp<MessageHandler> handler;
351         Message message;
352     };
353
354     const bool mAllowNonCallbacks; // immutable
355
356     int mWakeReadPipeFd;  // immutable
357     int mWakeWritePipeFd; // immutable
358     Mutex mLock;
359
360     Vector<MessageEnvelope> mMessageEnvelopes; // guarded by mLock
361     bool mSendingMessage; // guarded by mLock
362
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;
366
367     int mEpollFd; // immutable
368
369     // Locked list of file descriptor monitoring requests.
370     KeyedVector<int, Request> mRequests;  // guarded by mLock
371
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
377
378     int pollInner(int timeoutMillis);
379     void awoken();
380     void pushResponse(int events, const Request& request);
381
382     static void initTLSKey();
383     static void threadDestructor(void *st);
384 };
385
386 } // namespace android
387
388 #endif // UTILS_LOOPER_H