Looper.h revision 7901eb25c60b1df00050d6c3772505d8dcfcdab9
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 */ 867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int pollOnce(int timeoutMillis, 877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int* outFd = NULL, int* outEvents = NULL, void** outData = NULL); 887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Like pollOnce(), but performs all pending callbacks until all 917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * data has been consumed or a file descriptor is available with no callback. 927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This function will never return ALOOPER_POLL_CALLBACK. 937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int pollAll(int timeoutMillis, 957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int* outFd = NULL, int* outEvents = NULL, void** outData = NULL); 967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Wakes the poll asynchronously. 997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method returns immediately. 1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown void wake(); 1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Adds a new file descriptor to be polled by the looper. 1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the same file descriptor was previously added, it is replaced. 1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "fd" is the file descriptor to be added. 1107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "ident" is an identifier for this event, which is returned from ALooper_pollOnce(). 1117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback. 1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "events" are the poll events to wake up on. Typically this is ALOOPER_EVENT_INPUT. 1137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "callback" is the function to call when there is an event on the file descriptor. 1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * "data" is a private data pointer to supply to the callback. 1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * There are two main uses of this function: 1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * (1) If "callback" is non-NULL, then this function will be called when there is 1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * data on the file descriptor. It should execute any events it has pending, 1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * appropriately reading from the file descriptor. The 'ident' is ignored in this case. 1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce 1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * when its file descriptor has data available, requiring the caller to take 1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * care of processing it. 1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns 1 if the file descriptor was added, 0 if the arguments were invalid. 1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method may block briefly if it needs to wake the poll. 1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int addFd(int fd, int ident, 1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int events, ALooper_callbackFunc callback, void* data = NULL); 1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Removes a previously added file descriptor from the looper. 1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * When this method returns, it is safe to close the file descriptor since the looper 1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * will no longer have a reference to it. However, it is possible for the callback to 1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * already be running or for it to run one last time if the file descriptor was already 1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * signalled. Calling code is responsible for ensuring that this case is safely handled. 1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * For example, if the callback takes care of removing itself during its own execution either 1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * by returning 0 or by calling this method, then it can be guaranteed to not be invoked 1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * again at any later time unless registered anew. 1447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns 1 if the file descriptor was removed, 0 if none was previously registered. 1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method can be called on any thread. 1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * This method may block briefly if it needs to wake the poll. 1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int removeFd(int fd); 1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Prepares a looper associated with the calling thread, and returns it. 1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If the thread already has a looper, it is returned. Otherwise, a new 1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * one is created, associated with the thread, and returned. 1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0. 1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static sp<Looper> prepare(int opts); 1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Sets the given looper to be associated with the calling thread. 1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If another looper is already associated with the thread, it is replaced. 1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * 1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * If "looper" is NULL, removes the currently associated looper. 1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static void setForThread(const sp<Looper>& looper); 1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown /** 1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * Returns the looper associated with the calling thread, or NULL if 1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown * there is not one. 1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown */ 1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static sp<Looper> getForThread(); 1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownprivate: 1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct Request { 1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int fd; 1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int ident; 1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ALooper_callbackFunc callback; 1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown void* data; 1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown }; 1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct Response { 1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int events; 1857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Request request; 1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown }; 1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const bool mAllowNonCallbacks; // immutable 1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mEpollFd; // immutable 1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mWakeReadPipeFd; // immutable 1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int mWakeWritePipeFd; // immutable 1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // Locked list of file descriptor monitoring requests. 1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Mutex mLock; 1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown KeyedVector<int, Request> mRequests; 1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // This state is only used privately by pollOnce and does not require a lock since 1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown // it runs on a single thread. 2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Vector<Response> mResponses; 2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown size_t mResponseIndex; 2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int pollInner(int timeoutMillis); 2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown static void threadDestructor(void *st); 2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}; 2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android 2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif // UTILS_LOOPER_H 211