Looper.cpp revision 43550eee5bfeaf7832487a2285ae86be0f7ce561
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 167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <cutils/log.h> 177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Looper.h> 187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Timers.h> 197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <unistd.h> 217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <fcntl.h> 223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#include <limits.h> 237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android { 267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler --- 283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : 303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mHandler(handler) { 313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = mHandler.promote(); 353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (handler != NULL) { 363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper --- 423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8; 467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 51d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 52d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0; 53d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) : 553e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int wakeFds[2]; 587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = pipe(wakeFds); 597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mWakeReadPipeFd = wakeFds[0]; 627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mWakeWritePipeFd = wakeFds[1]; 637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", 667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown errno); 677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", 707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown errno); 717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 728d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // Allocate the epoll instance and register the wake pipe. 748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItem; 78d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.events = EPOLLIN; 807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.data.fd = mWakeReadPipeFd; 817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", 837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown errno); 848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else 858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // Add the wake pipe to the head of the request list with a null callback. 868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown struct pollfd requestedFd; 878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown requestedFd.fd = mWakeReadPipeFd; 888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown requestedFd.events = POLLIN; 898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequestedFds.push(requestedFd); 908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown Request request; 928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.fd = mWakeReadPipeFd; 938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.callback = NULL; 948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.ident = 0; 958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.data = NULL; 968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequests.push(request); 978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPolling = false; 998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mWaiters = 0; 1008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 1018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 1028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS 1038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPendingWakeTime = -1; 1048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPendingWakeCount = 0; 1058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCycles = 0; 1068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCountSum = 0; 1078d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeLatencySum = 0; 1088d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 1098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledPolls = 0; 1108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollCount = 0; 1118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollLatencySum = 0; 1128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollCount = 0; 1138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollLatencySum = 0; 1148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() { 1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mWakeReadPipeFd); 1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mWakeWritePipeFd); 1208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mEpollFd); 1228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 125d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() { 126d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 127d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 128d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown} 129d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) { 1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper* const self = static_cast<Looper*>(st); 1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (self != NULL) { 1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown self->decStrong((void*)threadDestructor); 1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper != NULL) { 1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper->incStrong((void*)threadDestructor); 1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 144d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown pthread_setspecific(gTLSKey, looper.get()); 1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (old != NULL) { 1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown old->decStrong((void*)threadDestructor); 1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() { 152d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 153d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 155d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown return (Looper*)pthread_getspecific(gTLSKey); 1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) { 1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; 1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> looper = Looper::getForThread(); 1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper == NULL) { 1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper = new Looper(allowNonCallbacks); 1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper::setForThread(looper); 1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGW("Looper already prepared for this thread with a different value for the " 1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return looper; 1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const { 1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return mAllowNonCallbacks; 1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = 0; 1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown while (mResponseIndex < mResponses.size()) { 1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 1813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown ALooper_callbackFunc callback = response.request.callback; 1823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (!callback) { 1833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int ident = response.request.ident; 1843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 1853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 1863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ pollOnce - returning signalled identifier %d: " 1893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown "fd=%d, events=0x%x, data=%p", 1903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, ident, fd, events, data); 1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 1923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outFd != NULL) *outFd = fd; 1933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outEvents != NULL) *outEvents = events; 1943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outData != NULL) *outData = data; 1953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return ident; 1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (result != 0) { 2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ pollOnce - returning result %d", this, result); 2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outFd != NULL) *outFd = 0; 2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outEvents != NULL) *outEvents = NULL; 2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outData != NULL) *outData = NULL; 2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollInner(timeoutMillis); 2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) { 2147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 2157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 2167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Adjust the timeout based on when the next message is due. 2193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 2203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 22143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 22243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (messageTimeoutMillis >= 0 22343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 22443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = messageTimeoutMillis; 2253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE 2273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 2283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, mNextMessageUptime - now, timeoutMillis); 2293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Poll. 2338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int result = ALOOPER_POLL_WAKE; 2348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.clear(); 2358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponseIndex = 0; 2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS 2388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 2398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 2408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 2437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 2448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else 2458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // Wait for wakeAndLock() waiters to run then set mPolling to true. 2468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mLock.lock(); 2478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown while (mWaiters != 0) { 2488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResume.wait(mLock); 2498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 2508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPolling = true; 2518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mLock.unlock(); 2528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown size_t requestedCount = mRequestedFds.size(); 2548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis); 2558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 2568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Acquire lock. 2583e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 2593e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 2603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll error. 2617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount < 0) { 262171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown if (errno == EINTR) { 2638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 265171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown LOGW("Poll failed with an unexpected error, errno=%d", errno); 2668d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown result = ALOOPER_POLL_ERROR; 2678d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll timeout. 2717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount == 0) { 2727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 2737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ pollOnce - timeout", this); 2747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown result = ALOOPER_POLL_TIMEOUT; 2768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Handle all events. 2807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 2817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 2827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 2859da1810050d8825e51dabdd0262173432d49c16cJeff Brown for (int i = 0; i < eventCount; i++) { 2869da1810050d8825e51dabdd0262173432d49c16cJeff Brown int fd = eventItems[i].data.fd; 2879da1810050d8825e51dabdd0262173432d49c16cJeff Brown uint32_t epollEvents = eventItems[i].events; 2889da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (fd == mWakeReadPipeFd) { 2899da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLIN) { 2908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown awoken(); 2917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 2929da1810050d8825e51dabdd0262173432d49c16cJeff Brown LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 2939da1810050d8825e51dabdd0262173432d49c16cJeff Brown } 2949da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 2959da1810050d8825e51dabdd0262173432d49c16cJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 2969da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (requestIndex >= 0) { 2979da1810050d8825e51dabdd0262173432d49c16cJeff Brown int events = 0; 2989da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; 2999da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; 3009da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; 3019da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; 3028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 3039da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 3049da1810050d8825e51dabdd0262173432d49c16cJeff Brown LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 3059da1810050d8825e51dabdd0262173432d49c16cJeff Brown "no longer registered.", epollEvents, fd); 3067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ; 3108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else 3118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown for (size_t i = 0; i < requestedCount; i++) { 3128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown const struct pollfd& requestedFd = mRequestedFds.itemAt(i); 3138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 3148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown short pollEvents = requestedFd.revents; 3158d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents) { 3168d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (requestedFd.fd == mWakeReadPipeFd) { 3178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLIN) { 3188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown awoken(); 3198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } else { 3208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents); 3218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } else { 3238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int events = 0; 3248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT; 3258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT; 3268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR; 3278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP; 3288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID; 3298d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown pushResponse(events, mRequests.itemAt(i)); 3308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3318d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (--eventCount == 0) { 3328d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown break; 3338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: 3378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // Set mPolling to false and wake up the wakeAndLock() waiters. 3388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPolling = false; 3398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mWaiters != 0) { 3408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mAwake.broadcast(); 3418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3428d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 3438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 3448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS 3458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC); 3468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledPolls += 1; 3478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (timeoutMillis == 0) { 3488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollCount += 1; 3498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollLatencySum += pollEndTime - pollStartTime; 3508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) { 3518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollCount += 1; 3528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime 3538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown - milliseconds_to_nanoseconds(timeoutMillis); 3548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) { 3568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this, 3578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount, 3588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount); 3598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledPolls = 0; 3608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollCount = 0; 3618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledZeroPollLatencySum = 0; 3628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollCount = 0; 3638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledTimeoutPollLatencySum = 0; 3648d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 3658d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 3667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke pending message callbacks. 3683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = LLONG_MAX; 3693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (mMessageEnvelopes.size() != 0) { 3703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 3713e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 3723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.uptime <= now) { 3733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Remove the envelope from the list. 3743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // We keep a strong reference to the handler until the call to handleMessage 3753e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 3763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // we reacquire our lock. 3773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // obtain handler 3783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 3793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown Message message = messageEnvelope.message; 3803e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(0); 3813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = true; 3823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 3833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 3853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 3863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, handler.get(), message.what); 3873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 3883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 3893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release handler 3903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 3923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = false; 3933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown result = ALOOPER_POLL_CALLBACK; 3943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } else { 3953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // The last message left at the head of the queue determines the next wakeup time. 3963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = messageEnvelope.uptime; 3973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown break; 3983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 3993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 4003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 4013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Release lock. 4023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 4033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 4043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke all response callbacks. 4057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 4067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const Response& response = mResponses.itemAt(i); 4073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown ALooper_callbackFunc callback = response.request.callback; 4083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (callback) { 4093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 4103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 4113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 4127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 4133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 4143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, callback, fd, events, data); 4157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int callbackResult = callback(fd, events, data); 4177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (callbackResult == 0) { 4183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown removeFd(fd); 4197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = ALOOPER_POLL_CALLBACK; 4217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 4247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 4277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (timeoutMillis <= 0) { 4287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result; 4297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown do { 4307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 4317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } while (result == ALOOPER_POLL_CALLBACK); 4327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 4337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 4357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 4367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 4397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (result != ALOOPER_POLL_CALLBACK) { 4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 4417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 44343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 44443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 44543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (timeoutMillis == 0) { 4467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return ALOOPER_POLL_TIMEOUT; 4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() { 4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ wake", this); 4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS 4588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled. 4598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mPendingWakeCount++ == 0) { 4608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC); 4618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 4628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 4638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 464171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown ssize_t nWrite; 465171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown do { 466171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 467171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown } while (nWrite == -1 && errno == EINTR); 468171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown 4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (nWrite != 1) { 4707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (errno != EAGAIN) { 4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGW("Could not write wake signal, errno=%d", errno); 4727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() { 4778d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE 4788d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOGD("%p ~ awoken", this); 4798d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 4808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS 4828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mPendingWakeCount == 0) { 4838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOGD("%p ~ awoken: spurious!", this); 4848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } else { 4858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCycles += 1; 4868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCountSum += mPendingWakeCount; 4878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime; 4888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPendingWakeCount = 0; 4898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mPendingWakeTime = -1; 4908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) { 4918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown LOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this, 4928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles, 4938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown float(mSampledWakeCountSum) / mSampledWakeCycles); 4948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCycles = 0; 4958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeCountSum = 0; 4968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mSampledWakeLatencySum = 0; 4978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 4988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 4998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 5008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown char buffer[16]; 5028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown ssize_t nRead; 5038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown do { 5048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 5058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 5068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 5078d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5088d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 5098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown Response response; 5108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.events = events; 5118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.request = request; 5128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.push(response); 5138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 5148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { 5167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 5177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 5187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown events, callback, data); 5197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 5207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (! callback) { 5227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (! mAllowNonCallbacks) { 5237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 5247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 5257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (ident < 0) { 5287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGE("Invalid attempt to set NULL callback with ident <= 0."); 5297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 5307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 5348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int epollEvents = 0; 5358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; 5368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; 5378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 5397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 5407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Request request; 5427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.fd = fd; 5437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.ident = ident; 5447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.callback = callback; 5457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.data = data; 5467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItem; 548d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 5497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.events = epollEvents; 5507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.data.fd = fd; 5517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 5537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 5547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 5557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 5567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); 5577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 5587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.add(fd, request); 5607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 5617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 5627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 5637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); 5647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 5657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.replaceValueAt(requestIndex, request); 5677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 5687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } // release lock 5698d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else 5708d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int pollEvents = 0; 5718d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN; 5728d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT; 5738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown wakeAndLock(); // acquire lock 5758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown struct pollfd requestedFd; 5778d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown requestedFd.fd = fd; 5788d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown requestedFd.events = pollEvents; 5798d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown Request request; 5818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.fd = fd; 5828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.ident = ident; 5838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.callback = callback; 5848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown request.data = data; 5858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown ssize_t index = getRequestIndexLocked(fd); 5868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (index < 0) { 5878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequestedFds.push(requestedFd); 5888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequests.push(request); 5898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } else { 5908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequestedFds.replaceAt(requestedFd, size_t(index)); 5918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequests.replaceAt(request, size_t(index)); 5928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 5938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 5948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mLock.unlock(); // release lock 5958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 5967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 5977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 5987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 5997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) { 6007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 6017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGD("%p ~ removeFd - fd=%d", this, fd); 6027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 6037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 6048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL 6057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 6067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 6077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 6087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 6097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 0; 6107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 6117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 6127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 6137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 6147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown LOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); 6157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 6167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 6177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 6187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.removeItemsAt(requestIndex); 6198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } // release lock 6207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 6218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else 6228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown wakeAndLock(); // acquire lock 6238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown ssize_t index = getRequestIndexLocked(fd); 6258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (index >= 0) { 6268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequestedFds.removeAt(size_t(index)); 6278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mRequests.removeAt(size_t(index)); 6288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 6298d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mLock.unlock(); // release lock 6318d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown return index >= 0; 6328d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 6337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 6347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 6358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifndef LOOPER_USES_EPOLL 6368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownssize_t Looper::getRequestIndexLocked(int fd) { 6378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown size_t requestCount = mRequestedFds.size(); 6388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown for (size_t i = 0; i < requestCount; i++) { 6408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mRequestedFds.itemAt(i).fd == fd) { 6418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown return i; 6428d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 6438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 6448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown return -1; 6468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 6478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::wakeAndLock() { 6498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mLock.lock(); 6508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mWaiters += 1; 6528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown while (mPolling) { 6538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown wake(); 6548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mAwake.wait(mLock); 6558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 6568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mWaiters -= 1; 6588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown if (mWaiters == 0) { 6598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResume.signal(); 6608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } 6618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 6628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 6638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 6643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 6653e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sendMessageAtTime(LLONG_MIN, handler, message); 6663e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 6673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 6693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 6703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 6713e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 6723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 6733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 6753e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 6763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 6773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 6783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, uptime, handler.get(), message.what); 6793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 6803e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t i = 0; 6823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 6833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 6843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t messageCount = mMessageEnvelopes.size(); 6863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 6873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown i += 1; 6883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 6893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 6913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 6923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 6933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 6943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // the call to wake() because the next thing the Looper will do after processing 6953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 6963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // not even matter whether this code is running on the Looper thread. 6973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (mSendingMessage) { 6983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return; 6993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 7013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Wake the poll loop only when we enqueue a new message at the head. 7033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (i == 0) { 7043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown wake(); 7053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 7073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 7093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 7103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 7113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 7123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 7143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 7153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 7173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 7183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler) { 7193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 7203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 7233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 7243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 7263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 7273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown LOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 7283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 7293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 7313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 7323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 7343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 7353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler 7363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown && messageEnvelope.message.what == what) { 7373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 7383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 7403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 7413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 7423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 7437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android 744