Looper.h revision 905682a19609e862633f01e69bec58384df2cdf7
17901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/* 27901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Copyright (C) 2010 The Android Open Source Project 37901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 47901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 57901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * you may not use this file except in compliance with the License. 67901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * You may obtain a copy of the License at 77901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 87901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 97901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Unless required by applicable law or agreed to in writing, software 117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * See the License for the specific language governing permissions and 147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * limitations under the License. 157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#ifndef UTILS_LOOPER_H 187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define UTILS_LOOPER_H 197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/threads.h> 217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/RefBase.h> 227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/KeyedVector.h> 237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <android/looper.h> 257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/* 277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Declare a concrete type for the NDK's looper forward declaration. 287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstruct ALooper { 307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}; 317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android { 337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown/** 357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * A polling loop that supports monitoring file descriptor events, optionally 367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * using callbacks. The implementation uses epoll() internally. 377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * A looper can be associated with a thread although there is no requirement that it must be. 397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownclass Looper : public ALooper, public RefBase { 417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprotected: 427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown virtual ~Looper(); 437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownpublic: 457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Creates a looper. 477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If allowNonCallbaks is true, the looper will allow file descriptors to be 497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * registered without associated callbacks. This assumes that the caller of 507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * pollOnce() is prepared to handle callback-less events itself. 517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper(bool allowNonCallbacks); 537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns whether this looper instance allows the registration of file descriptors 567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * using identifiers instead of callbacks. 577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown bool getAllowNonCallbacks() const; 597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Waits for events to be available, with optional timeout in milliseconds. 627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Invokes callbacks for all file descriptors on which an event occurred. 637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the timeout is zero, returns immediately without blocking. 657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the timeout is negative, waits indefinitely until an event appears. 667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before 687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * the timeout expired and no callbacks were invoked and no other file 697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * descriptors were ready. 707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked. 727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given 747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * timeout expired. 757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns ALOOPER_POLL_ERROR if an error occurred. 777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns a value >= 0 containing an identifier if its file descriptor has data 797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * and it has no callback function (requiring the caller here to handle it). 807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * In this (and only this) case outFd, outEvents and outData will contain the poll 817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * events and data associated with the fd, otherwise they will be set to NULL. 827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method does not return until it has finished invoking the appropriate callbacks 847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * for all file descriptors that were signalled. 857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 86905682a19609e862633f01e69bec58384df2cdf7Jeff Brown int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData); 87905682a19609e862633f01e69bec58384df2cdf7Jeff Brown inline int pollOnce(int timeoutMillis) { 88905682a19609e862633f01e69bec58384df2cdf7Jeff Brown return pollOnce(timeoutMillis, NULL, NULL, NULL); 89905682a19609e862633f01e69bec58384df2cdf7Jeff Brown } 907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Like pollOnce(), but performs all pending callbacks until all 937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * data has been consumed or a file descriptor is available with no callback. 947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This function will never return ALOOPER_POLL_CALLBACK. 957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 96905682a19609e862633f01e69bec58384df2cdf7Jeff Brown int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData); 97905682a19609e862633f01e69bec58384df2cdf7Jeff Brown inline int pollAll(int timeoutMillis) { 98905682a19609e862633f01e69bec58384df2cdf7Jeff Brown return pollAll(timeoutMillis, NULL, NULL, NULL); 99905682a19609e862633f01e69bec58384df2cdf7Jeff Brown } 1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Wakes the poll asynchronously. 1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method returns immediately. 1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown void wake(); 1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Adds a new file descriptor to be polled by the looper. 1117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the same file descriptor was previously added, it is replaced. 1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "fd" is the file descriptor to be added. 1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "ident" is an identifier for this event, which is returned from ALooper_pollOnce(). 1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. 1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. 1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "callback" is the function to call when there is an event on the file descriptor. 1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "data" is a private data pointer to supply to the callback. 1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * There are two main uses of this function: 1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * (1) If "callback" is non-NULL, then this function will be called when there is 1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * data on the file descriptor. It should execute any events it has pending, 1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * appropriately reading from the file descriptor. The 'ident' is ignored in this case. 1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce 1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * when its file descriptor has data available, requiring the caller to take 1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * care of processing it. 1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns 1 if the file descriptor was added, 0 if the arguments were invalid. 1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method may block briefly if it needs to wake the poll. 1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 135905682a19609e862633f01e69bec58384df2cdf7Jeff Brown int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data); 1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Removes a previously added file descriptor from the looper. 1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * When this method returns, it is safe to close the file descriptor since the looper 1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * will no longer have a reference to it. However, it is possible for the callback to 1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * already be running or for it to run one last time if the file descriptor was already 1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * signalled. Calling code is responsible for ensuring that this case is safely handled. 1447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * For example, if the callback takes care of removing itself during its own execution either 1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * by returning 0 or by calling this method, then it can be guaranteed to not be invoked 1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * again at any later time unless registered anew. 1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns 1 if the file descriptor was removed, 0 if none was previously registered. 1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method may block briefly if it needs to wake the poll. 1527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int removeFd(int fd); 1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Prepares a looper associated with the calling thread, and returns it. 1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the thread already has a looper, it is returned. Otherwise, a new 1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * one is created, associated with the thread, and returned. 1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. 1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static sp<Looper> prepare(int opts); 1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Sets the given looper to be associated with the calling thread. 1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If another looper is already associated with the thread, it is replaced. 1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If "looper" is NULL, removes the currently associated looper. 1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static void setForThread(const sp<Looper>& looper); 1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns the looper associated with the calling thread, or NULL if 1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * there is not one. 1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static sp<Looper> getForThread(); 1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprivate: 1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct Request { 1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int fd; 1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int ident; 1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ALooper_callbackFunc callback; 1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown void* data; 1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown }; 1857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct Response { 1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int events; 1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Request request; 1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown }; 1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const bool mAllowNonCallbacks; // immutable 1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mEpollFd; // immutable 1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mWakeReadPipeFd; // immutable 1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mWakeWritePipeFd; // immutable 1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // Locked list of file descriptor monitoring requests. 1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Mutex mLock; 1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown KeyedVector<int, Request> mRequests; 2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // This state is only used privately by pollOnce and does not require a lock since 2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // it runs on a single thread. 2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Vector<Response> mResponses; 2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown size_t mResponseIndex; 2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int pollInner(int timeoutMillis); 2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static void threadDestructor(void *st); 2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}; 2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android 2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif // UTILS_LOOPER_H 214