Looper.cpp revision 22dbf3947fedf988e714a4703ddf85fc41413f90
17901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// 27901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Copyright 2010 The Android Open Source Project 37901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// 47901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// A looper implementation based on epoll(). 57901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// 67901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define LOG_TAG "Looper" 77901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 87901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//#define LOG_NDEBUG 0 97901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs poll and wake interactions. 117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_POLL_AND_WAKE 0 127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs callback registration and invocation. 147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_CALLBACKS 0 157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1666ce3e08c5632a20ea66bde6dd76397041edf034Mark Salyzyn#include <utils/Looper.h> 1722dbf3947fedf988e714a4703ddf85fc41413f90Mathias Agopian#include <sys/eventfd.h> 187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android { 207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler --- 223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : 243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mHandler(handler) { 253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 27dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownWeakMessageHandler::~WeakMessageHandler() { 28dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 29dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = mHandler.promote(); 323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (handler != NULL) { 333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 38dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown// --- SimpleLooperCallback --- 39dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 401693d7e48f976c2615100378c7e98d245e0213beBrian CarlstromSimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) : 41dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown mCallback(callback) { 42dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 43dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 44dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownSimpleLooperCallback::~SimpleLooperCallback() { 45dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 46dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 47dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint SimpleLooperCallback::handleEvent(int fd, int events, void* data) { 48dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown return mCallback(fd, events, data); 49dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 50dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 51dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper --- 533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8; 567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 60d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 61d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0; 62d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) : 643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 65e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false), 667a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 67c68c8862f954fdd7c6cc6ebc331bba969bd06919Nick Kralevich mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); 685b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s", 695b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes strerror(errno)); 707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 71e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown AutoMutex _l(mLock); 72e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown rebuildEpollLocked(); 737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() { 768892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn close(mWakeEventFd); 7748c35dbe5044ef07afda15ccc105a7018006eca6John Reck mWakeEventFd = -1; 78e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (mEpollFd >= 0) { 79e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown close(mEpollFd); 80e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 83d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() { 84d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 85d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 86d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown} 87d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) { 897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper* const self = static_cast<Looper*>(st); 907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (self != NULL) { 917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown self->decStrong((void*)threadDestructor); 927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper != NULL) { 997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper->incStrong((void*)threadDestructor); 1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 102d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown pthread_setspecific(gTLSKey, looper.get()); 1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (old != NULL) { 1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown old->decStrong((void*)threadDestructor); 1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() { 110d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 111d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 113d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown return (Looper*)pthread_getspecific(gTLSKey); 1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) { 1171693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS; 1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> looper = Looper::getForThread(); 1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper == NULL) { 1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper = new Looper(allowNonCallbacks); 1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper::setForThread(looper); 1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 12461d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block ALOGW("Looper already prepared for this thread with a different value for the " 1251693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return looper; 1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const { 1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return mAllowNonCallbacks; 1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 134e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::rebuildEpollLocked() { 135e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Close old epoll instance if we have one. 136e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (mEpollFd >= 0) { 137e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#if DEBUG_CALLBACKS 138e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this); 139e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#endif 140e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown close(mEpollFd); 141e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 142e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 143e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Allocate the new epoll instance and register the wake pipe. 144e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 1455b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno)); 146e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 147e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown struct epoll_event eventItem; 148e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 149e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown eventItem.events = EPOLLIN; 1508892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn eventItem.data.fd = mWakeEventFd; 1518892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem); 1525b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s", 1535b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes strerror(errno)); 154e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 155e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown for (size_t i = 0; i < mRequests.size(); i++) { 156e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown const Request& request = mRequests.valueAt(i); 157e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown struct epoll_event eventItem; 158e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown request.initEventItem(&eventItem); 159e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 160e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem); 161e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (epollResult < 0) { 1625b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s", 1635b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes request.fd, strerror(errno)); 164e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 165e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 166e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown} 167e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 168e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::scheduleEpollRebuildLocked() { 169e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (!mEpollRebuildRequired) { 170e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#if DEBUG_CALLBACKS 171e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown ALOGD("%p ~ scheduleEpollRebuildLocked - scheduling epoll set rebuild", this); 172e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#endif 173e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown mEpollRebuildRequired = true; 174e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown wake(); 175e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 176e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown} 177e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = 0; 1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown while (mResponseIndex < mResponses.size()) { 1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 183dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown int ident = response.request.ident; 184dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (ident >= 0) { 1853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 1863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 1873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 189eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - returning signalled identifier %d: " 1903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown "fd=%d, events=0x%x, data=%p", 1913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, ident, fd, events, data); 1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 1933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outFd != NULL) *outFd = fd; 1943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outEvents != NULL) *outEvents = events; 1953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outData != NULL) *outData = data; 1963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return ident; 1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (result != 0) { 2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 202eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - returning result %d", this, result); 2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outFd != NULL) *outFd = 0; 205dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (outEvents != NULL) *outEvents = 0; 2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outData != NULL) *outData = NULL; 2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollInner(timeoutMillis); 2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) { 2157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 216eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 2177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Adjust the timeout based on when the next message is due. 2203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 2213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 22243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 22343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (messageTimeoutMillis >= 0 22443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 22543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = messageTimeoutMillis; 2263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE 2287a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d", 2293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, mNextMessageUptime - now, timeoutMillis); 2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 2333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Poll. 2341693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom int result = POLL_WAKE; 2358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.clear(); 2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponseIndex = 0; 2378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 23819159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn // We are about to idle. 23927e5721860142b1b20081b535c55e7917366385fJeff Brown mPolling = true; 24019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 2417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 2438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 24419159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn // No longer idling. 24527e5721860142b1b20081b535c55e7917366385fJeff Brown mPolling = false; 24619159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 2473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Acquire lock. 2483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 2493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 250e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Rebuild epoll set if needed. 251e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (mEpollRebuildRequired) { 252e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown mEpollRebuildRequired = false; 253e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown rebuildEpollLocked(); 254e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown goto Done; 255e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown } 256e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 2573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll error. 2587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount < 0) { 259171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown if (errno == EINTR) { 2608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2626ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGW("Poll failed with an unexpected error: %s", strerror(errno)); 2631693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_ERROR; 2648d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll timeout. 2687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount == 0) { 2697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 270eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - timeout", this); 2717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2721693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_TIMEOUT; 2738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Handle all events. 2777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 278eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 2797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2819da1810050d8825e51dabdd0262173432d49c16cJeff Brown for (int i = 0; i < eventCount; i++) { 2829da1810050d8825e51dabdd0262173432d49c16cJeff Brown int fd = eventItems[i].data.fd; 2839da1810050d8825e51dabdd0262173432d49c16cJeff Brown uint32_t epollEvents = eventItems[i].events; 2848892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn if (fd == mWakeEventFd) { 2859da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLIN) { 2868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown awoken(); 2877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 2888892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents); 2899da1810050d8825e51dabdd0262173432d49c16cJeff Brown } 2909da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 2919da1810050d8825e51dabdd0262173432d49c16cJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 2929da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (requestIndex >= 0) { 2939da1810050d8825e51dabdd0262173432d49c16cJeff Brown int events = 0; 2941693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLIN) events |= EVENT_INPUT; 2951693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT; 2961693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLERR) events |= EVENT_ERROR; 2971693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP; 2988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 2999da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 30061d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 3019da1810050d8825e51dabdd0262173432d49c16cJeff Brown "no longer registered.", epollEvents, fd); 3027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ; 3068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 3073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke pending message callbacks. 3083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = LLONG_MAX; 3093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (mMessageEnvelopes.size() != 0) { 3103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 3113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 3123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.uptime <= now) { 3133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Remove the envelope from the list. 3143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // We keep a strong reference to the handler until the call to handleMessage 3153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 3163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // we reacquire our lock. 3173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // obtain handler 3183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 3193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown Message message = messageEnvelope.message; 3203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(0); 3213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = true; 3223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 3233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 325eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 3263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, handler.get(), message.what); 3273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 3283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 3293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release handler 3303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 3323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = false; 3331693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_CALLBACK; 3343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } else { 3353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // The last message left at the head of the queue determines the next wakeup time. 3363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = messageEnvelope.uptime; 3373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown break; 3383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 3393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 3403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Release lock. 3423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 3433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke all response callbacks. 3457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 346dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown Response& response = mResponses.editItemAt(i); 3471693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (response.request.ident == POLL_CALLBACK) { 3483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 3493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 3503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 3517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 352eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 353dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown this, response.request.callback.get(), fd, events, data); 3547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 3557a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // Invoke the callback. Note that the file descriptor may be closed by 3567a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // the callback (and potentially even reused) before the function returns so 3577a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // we need to be a little careful when removing the file descriptor afterwards. 358dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown int callbackResult = response.request.callback->handleEvent(fd, events, data); 3597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (callbackResult == 0) { 3607a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown removeFd(fd, response.request.seq); 3617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3627a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown 363dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown // Clear the callback reference in the response structure promptly because we 364dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown // will not clear the response vector itself until the next poll. 365dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown response.request.callback.clear(); 3661693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_CALLBACK; 3677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 3717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 3737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (timeoutMillis <= 0) { 3747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result; 3757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown do { 3767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 3771693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom } while (result == POLL_CALLBACK); 3787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 3807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 3817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 3827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 3847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 3851693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (result != POLL_CALLBACK) { 3867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 38943550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 39043550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 39143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (timeoutMillis == 0) { 3921693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom return POLL_TIMEOUT; 3937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 3977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() { 3997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 400eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ wake", this); 4017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4038892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn uint64_t inc = 1; 4048892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t))); 4058892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn if (nWrite != sizeof(uint64_t)) { 4067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (errno != EAGAIN) { 40748c35dbe5044ef07afda15ccc105a7018006eca6John Reck LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s", 40848c35dbe5044ef07afda15ccc105a7018006eca6John Reck mWakeEventFd, strerror(errno)); 4097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() { 4148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE 415eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ awoken", this); 4168d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 4178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4188892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn uint64_t counter; 4198892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t))); 4208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 4218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 4238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown Response response; 4248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.events = events; 4258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.request = request; 4268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.push(response); 4278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 4288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4291693d7e48f976c2615100378c7e98d245e0213beBrian Carlstromint Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) { 430dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); 431dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 432dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 433dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { 4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 435eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 436dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown events, callback.get(), data); 4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 439dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (!callback.get()) { 4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (! mAllowNonCallbacks) { 4411b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (ident < 0) { 446dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown ALOGE("Invalid attempt to set NULL callback with ident < 0."); 4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 449dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown } else { 4501693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom ident = POLL_CALLBACK; 4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Request request; 4577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.fd = fd; 4587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.ident = ident; 459e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown request.events = events; 460e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown request.seq = mNextRequestSeq++; 4617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.callback = callback; 4627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.data = data; 4637a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1 4647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItem; 466e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown request.initEventItem(&eventItem); 4677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 4707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 4726ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno)); 4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.add(fd, request); 4767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 4777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 4787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 4797a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (errno == ENOENT) { 480e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Tolerate ENOENT because it means that an older file descriptor was 4817a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // closed before its callback was unregistered and meanwhile a new 4827a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // file descriptor with the same number has been created and is now 483e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // being registered for the first time. This error may occur naturally 484e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // when a callback has the side-effect of closing the file descriptor 485e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // before returning and unregistering itself. Callback sequence number 486e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // checks further ensure that the race is benign. 487e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // 488e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Unfortunately due to kernel limitations we need to rebuild the epoll 489e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // set from scratch because it may contain an old file handle that we are 490e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // now unable to remove since its file descriptor is no longer valid. 491e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // No such problem would have occurred if we were using the poll system 492e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // call instead, but that approach carries others disadvantages. 4937a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS 4947a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor " 4955b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes "being recycled, falling back on EPOLL_CTL_ADD: %s", 4965b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes this, strerror(errno)); 4977a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif 4987a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 4997a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (epollResult < 0) { 5005b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes ALOGE("Error modifying or adding epoll events for fd %d: %s", 5015b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes fd, strerror(errno)); 5027a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown return -1; 5037a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } 504e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown scheduleEpollRebuildLocked(); 5057a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } else { 5065b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno)); 5077a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown return -1; 5087a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } 5097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.replaceValueAt(requestIndex, request); 5117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } // release lock 5137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 5147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 5157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) { 5177a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown return removeFd(fd, -1); 5187a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown} 5197a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown 5207a0310ef678edcf06acfd230617c427a788e58f8Jeff Brownint Looper::removeFd(int fd, int seq) { 5217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 5227a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ removeFd - fd=%d, seq=%d", this, fd, seq); 5237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 5247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 5267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 5277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 5287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 5297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 0; 5307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5327a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // Check the sequence number if one was given. 5337a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (seq != -1 && mRequests.valueAt(requestIndex).seq != seq) { 5347a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS 5357a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ removeFd - sequence number mismatch, oldSeq=%d", 5367a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown this, mRequests.valueAt(requestIndex).seq); 5377a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif 5387a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown return 0; 5397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5417a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // Always remove the FD from the request map even if an error occurs while 5427a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // updating the epoll set so that we avoid accidentally leaking callbacks. 5437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.removeItemsAt(requestIndex); 5447a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown 5457a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 5467a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (epollResult < 0) { 5477a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown if (seq != -1 && (errno == EBADF || errno == ENOENT)) { 548e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Tolerate EBADF or ENOENT when the sequence number is known because it 5497a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown // means that the file descriptor was closed before its callback was 550e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // unregistered. This error may occur naturally when a callback has the 551e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // side-effect of closing the file descriptor before returning and 552e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // unregistering itself. 553e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // 554e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // Unfortunately due to kernel limitations we need to rebuild the epoll 555e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // set from scratch because it may contain an old file handle that we are 556e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // now unable to remove since its file descriptor is no longer valid. 557e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // No such problem would have occurred if we were using the poll system 558e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown // call instead, but that approach carries others disadvantages. 5597a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS 5607a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ removeFd - EPOLL_CTL_DEL failed due to file descriptor " 5615b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes "being closed: %s", this, strerror(errno)); 5627a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif 563e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown scheduleEpollRebuildLocked(); 5647a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } else { 56518a574f715b767ee8a2f02903c883d571b42409fJeff Brown // Some other error occurred. This is really weird because it means 56618a574f715b767ee8a2f02903c883d571b42409fJeff Brown // our list of callbacks got out of sync with the epoll set somehow. 56718a574f715b767ee8a2f02903c883d571b42409fJeff Brown // We defensively rebuild the epoll set to avoid getting spurious 56818a574f715b767ee8a2f02903c883d571b42409fJeff Brown // notifications with nowhere to go. 5695b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno)); 57018a574f715b767ee8a2f02903c883d571b42409fJeff Brown scheduleEpollRebuildLocked(); 5717a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown return -1; 5727a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } 5737a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown } 5748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } // release lock 5757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 5767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 5777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 579aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 580aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown sendMessageAtTime(now, handler, message); 5813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 5843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 5853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 5863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 5873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 5903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 5913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 5927a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown ALOGD("%p ~ sendMessageAtTime - uptime=%" PRId64 ", handler=%p, what=%d", 5933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, uptime, handler.get(), message.what); 5943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 5953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t i = 0; 5973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 5983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 5993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t messageCount = mMessageEnvelopes.size(); 6013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 6023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown i += 1; 6033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 6063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 6073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 6093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // the call to wake() because the next thing the Looper will do after processing 6103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 6113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // not even matter whether this code is running on the Looper thread. 6123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (mSendingMessage) { 6133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return; 6143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 6163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Wake the poll loop only when we enqueue a new message at the head. 6183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (i == 0) { 6193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown wake(); 6203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 6223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 6243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 625eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 6263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 6273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 6293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 6303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 6323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 6333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler) { 6343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 6353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 6383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 6393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 6413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 642eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 6433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 6443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 6463e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 6473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 6493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 6503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler 6513e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown && messageEnvelope.message.what == what) { 6523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 6533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6543e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6553e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 6563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 6573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 65827e5721860142b1b20081b535c55e7917366385fJeff Brownbool Looper::isPolling() const { 65927e5721860142b1b20081b535c55e7917366385fJeff Brown return mPolling; 66019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn} 66119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 662e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::Request::initEventItem(struct epoll_event* eventItem) const { 663e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown int epollEvents = 0; 664e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (events & EVENT_INPUT) epollEvents |= EPOLLIN; 665e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT; 666e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 667e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 668e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown eventItem->events = epollEvents; 669e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown eventItem->data.fd = fd; 670e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown} 671e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown 67217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin CrossMessageHandler::~MessageHandler() { } 67317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross 67417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin CrossLooperCallback::~LooperCallback() { } 67517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross 6767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android 677