Looper.cpp revision 6ed68cc412752e4c78755df9a1516e610ec66fa8
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 206ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <errno.h> 217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <fcntl.h> 223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#include <limits.h> 236ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <string.h> 246ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <unistd.h> 257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android { 287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler --- 303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : 323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mHandler(handler) { 333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 35dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownWeakMessageHandler::~WeakMessageHandler() { 36dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 37dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = mHandler.promote(); 403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (handler != NULL) { 413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 46dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown// --- SimpleLooperCallback --- 47dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 481693d7e48f976c2615100378c7e98d245e0213beBrian CarlstromSimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) : 49dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown mCallback(callback) { 50dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 51dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 52dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownSimpleLooperCallback::~SimpleLooperCallback() { 53dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 54dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 55dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint SimpleLooperCallback::handleEvent(int fd, int events, void* data) { 56dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown return mCallback(fd, events, data); 57dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 58dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 59dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper --- 613e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8; 647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 68d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 69d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0; 70d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) : 723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int wakeFds[2]; 757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = pipe(wakeFds); 766ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe: %s", strerror(errno)); 777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mWakeReadPipeFd = wakeFds[0]; 797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mWakeWritePipeFd = wakeFds[1]; 807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking: %s", 836ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes strerror(errno)); 847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 866ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking: %s", 876ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes strerror(errno)); 887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 8919159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn mIdling = false; 9019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown // Allocate the epoll instance and register the wake pipe. 928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 936ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno)); 948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItem; 96d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.events = EPOLLIN; 987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.data.fd = mWakeReadPipeFd; 997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 1006ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance: %s", 1016ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes strerror(errno)); 1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() { 1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mWakeReadPipeFd); 1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mWakeWritePipeFd); 1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown close(mEpollFd); 1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 110d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() { 111d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 112d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 113d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown} 114d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown 1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) { 1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper* const self = static_cast<Looper*>(st); 1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (self != NULL) { 1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown self->decStrong((void*)threadDestructor); 1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper != NULL) { 1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper->incStrong((void*)threadDestructor); 1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 129d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown pthread_setspecific(gTLSKey, looper.get()); 1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (old != NULL) { 1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown old->decStrong((void*)threadDestructor); 1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() { 137d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 138d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 140d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown return (Looper*)pthread_getspecific(gTLSKey); 1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) { 1441693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS; 1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown sp<Looper> looper = Looper::getForThread(); 1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper == NULL) { 1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown looper = new Looper(allowNonCallbacks); 1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Looper::setForThread(looper); 1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 15161d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block ALOGW("Looper already prepared for this thread with a different value for the " 1521693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return looper; 1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const { 1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return mAllowNonCallbacks; 1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = 0; 1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown while (mResponseIndex < mResponses.size()) { 1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 166dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown int ident = response.request.ident; 167dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (ident >= 0) { 1683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 1693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 1703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 172eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - returning signalled identifier %d: " 1733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown "fd=%d, events=0x%x, data=%p", 1743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, ident, fd, events, data); 1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 1763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outFd != NULL) *outFd = fd; 1773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outEvents != NULL) *outEvents = events; 1783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (outData != NULL) *outData = data; 1793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return ident; 1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (result != 0) { 1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 185eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - returning result %d", this, result); 1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outFd != NULL) *outFd = 0; 188dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (outEvents != NULL) *outEvents = 0; 1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (outData != NULL) *outData = NULL; 1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollInner(timeoutMillis); 1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) { 1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 199eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Adjust the timeout based on when the next message is due. 2033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 2043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 20543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 20643550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (messageTimeoutMillis >= 0 20743550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 20843550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = messageTimeoutMillis; 2093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE 211eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 2123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, mNextMessageUptime - now, timeoutMillis); 2133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 2143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 2153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 2163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Poll. 2171693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom int result = POLL_WAKE; 2188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.clear(); 2198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponseIndex = 0; 2208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 22119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn // We are about to idle. 22219159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn mIdling = true; 22319159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 2247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 2257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 2268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 22719159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn // No longer idling. 22819159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn mIdling = false; 22919159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Acquire lock. 2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 2333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll error. 2347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount < 0) { 235171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown if (errno == EINTR) { 2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2386ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGW("Poll failed with an unexpected error: %s", strerror(errno)); 2391693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_ERROR; 2408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Check for poll timeout. 2447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (eventCount == 0) { 2457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 246eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - timeout", this); 2477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2481693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_TIMEOUT; 2498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown goto Done; 2507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 2523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Handle all events. 2537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 254eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 2557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 2568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2579da1810050d8825e51dabdd0262173432d49c16cJeff Brown for (int i = 0; i < eventCount; i++) { 2589da1810050d8825e51dabdd0262173432d49c16cJeff Brown int fd = eventItems[i].data.fd; 2599da1810050d8825e51dabdd0262173432d49c16cJeff Brown uint32_t epollEvents = eventItems[i].events; 2609da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (fd == mWakeReadPipeFd) { 2619da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (epollEvents & EPOLLIN) { 2628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown awoken(); 2637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 26461d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 2659da1810050d8825e51dabdd0262173432d49c16cJeff Brown } 2669da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 2679da1810050d8825e51dabdd0262173432d49c16cJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 2689da1810050d8825e51dabdd0262173432d49c16cJeff Brown if (requestIndex >= 0) { 2699da1810050d8825e51dabdd0262173432d49c16cJeff Brown int events = 0; 2701693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLIN) events |= EVENT_INPUT; 2711693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT; 2721693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLERR) events |= EVENT_ERROR; 2731693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP; 2748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 2759da1810050d8825e51dabdd0262173432d49c16cJeff Brown } else { 27661d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 2779da1810050d8825e51dabdd0262173432d49c16cJeff Brown "no longer registered.", epollEvents, fd); 2787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 2818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ; 2828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 2833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke pending message callbacks. 2843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = LLONG_MAX; 2853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (mMessageEnvelopes.size() != 0) { 2863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 2873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 2883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.uptime <= now) { 2893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Remove the envelope from the list. 2903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // We keep a strong reference to the handler until the call to handleMessage 2913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 2923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // we reacquire our lock. 2933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // obtain handler 2943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 2953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown Message message = messageEnvelope.message; 2963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(0); 2973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = true; 2983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 2993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 301eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 3023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, handler.get(), message.what); 3033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 3043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown handler->handleMessage(message); 3053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release handler 3063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.lock(); 3083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mSendingMessage = false; 3091693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_CALLBACK; 3103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } else { 3113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // The last message left at the head of the queue determines the next wakeup time. 3123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mNextMessageUptime = messageEnvelope.uptime; 3133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown break; 3143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 3153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 3163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Release lock. 3183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mLock.unlock(); 3193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 3203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Invoke all response callbacks. 3217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 322dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown Response& response = mResponses.editItemAt(i); 3231693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (response.request.ident == POLL_CALLBACK) { 3243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int fd = response.request.fd; 3253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown int events = response.events; 3263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown void* data = response.request.data; 3277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 328eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 329dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown this, response.request.callback.get(), fd, events, data); 3307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 331dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown int callbackResult = response.request.callback->handleEvent(fd, events, data); 3327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (callbackResult == 0) { 3333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown removeFd(fd); 3347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 335dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown // Clear the callback reference in the response structure promptly because we 336dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown // will not clear the response vector itself until the next poll. 337dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown response.request.callback.clear(); 3381693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom result = POLL_CALLBACK; 3397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 3437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 3457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (timeoutMillis <= 0) { 3467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result; 3477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown do { 3487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 3491693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom } while (result == POLL_CALLBACK); 3507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 3527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 3537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 3547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown for (;;) { 3567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 3571693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (result != POLL_CALLBACK) { 3587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return result; 3597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 36143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 36243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 36343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown if (timeoutMillis == 0) { 3641693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom return POLL_TIMEOUT; 3657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 3697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() { 3717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE 372eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ wake", this); 3737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 3747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 375171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown ssize_t nWrite; 376171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown do { 377171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 378171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown } while (nWrite == -1 && errno == EINTR); 379171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown 3807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (nWrite != 1) { 3817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (errno != EAGAIN) { 3826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGW("Could not write wake signal: %s", strerror(errno)); 3837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 3857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 3867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 3878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() { 3888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE 389eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ awoken", this); 3908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif 3918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 3928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown char buffer[16]; 3938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown ssize_t nRead; 3948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown do { 3958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 3968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 3978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 3988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 3998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 4008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown Response response; 4018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.events = events; 4028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown response.request = request; 4038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown mResponses.push(response); 4048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown} 4058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4061693d7e48f976c2615100378c7e98d245e0213beBrian Carlstromint Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) { 407dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); 408dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown} 409dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown 410dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { 4117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 412eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 413dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown events, callback.get(), data); 4147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 416dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown if (!callback.get()) { 4177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (! mAllowNonCallbacks) { 4181b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 4197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (ident < 0) { 423dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown ALOGE("Invalid attempt to set NULL callback with ident < 0."); 4247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 426dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown } else { 4271693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom ident = POLL_CALLBACK; 4287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown int epollEvents = 0; 4311693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (events & EVENT_INPUT) epollEvents |= EPOLLIN; 4321693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT; 4338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown 4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 4357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 4367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown Request request; 4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.fd = fd; 4397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.ident = ident; 4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.callback = callback; 4417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown request.data = data; 4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown struct epoll_event eventItem; 444d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 4457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.events = epollEvents; 4467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown eventItem.data.fd = fd; 4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 4497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 4507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 4526ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno)); 4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.add(fd, request); 4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } else { 4577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 4587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 4596ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno)); 4607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.replaceValueAt(requestIndex, request); 4637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } // release lock 4657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 4667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) { 4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS 470eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ removeFd - fd=%d", this, fd); 4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif 4727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown { // acquire lock 4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown AutoMutex _l(mLock); 4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 4767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (requestIndex < 0) { 4777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 0; 4787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 4817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown if (epollResult < 0) { 4826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno)); 4837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return -1; 4847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown } 4857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown mRequests.removeItemsAt(requestIndex); 4878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown } // release lock 4887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown return 1; 4897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} 4907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown 4913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 492aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 493aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown sendMessageAtTime(now, handler, message); 4943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 4953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 4963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 4973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 4983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 4993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 5003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 5033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const Message& message) { 5043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 505eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 5063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown this, uptime, handler.get(), message.what); 5073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 5083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t i = 0; 5103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 5113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 5123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown size_t messageCount = mMessageEnvelopes.size(); 5143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 5153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown i += 1; 5163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 5193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 5203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 5223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // the call to wake() because the next thing the Looper will do after processing 5233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 5243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // not even matter whether this code is running on the Looper thread. 5253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (mSendingMessage) { 5263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown return; 5273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 5293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown // Wake the poll loop only when we enqueue a new message at the head. 5313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (i == 0) { 5323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown wake(); 5333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 5373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 538eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 5393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 5403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 5423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 5433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 5453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 5463e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler) { 5473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 5483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 5513e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 5543e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS 555eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 5563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif 5573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5583e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown { // acquire lock 5593e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown AutoMutex _l(mLock); 5603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 5613e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 5623e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 5633e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown if (messageEnvelope.handler == handler 5643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown && messageEnvelope.message.what == what) { 5653e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown mMessageEnvelopes.removeAt(i); 5663e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } 5683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown } // release lock 5693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown} 5703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown 57119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackbornbool Looper::isIdling() const { 57219159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn return mIdling; 57319159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn} 57419159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn 5757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android 576