14fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// 24fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// Copyright 2010 The Android Open Source Project 34fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// 44fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// A looper implementation based on epoll(). 54fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// 64fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#define LOG_TAG "Looper" 74fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 84fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown//#define LOG_NDEBUG 0 94fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 104fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// Debugs poll and wake interactions. 114fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#define DEBUG_POLL_AND_WAKE 0 124fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 134fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// Debugs callback registration and invocation. 144fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#define DEBUG_CALLBACKS 0 154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <cutils/log.h> 174fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <utils/Looper.h> 184fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <utils/Timers.h> 194fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 204fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <unistd.h> 214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#include <fcntl.h> 2205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#include <limits.h> 234fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 244fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 254fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownnamespace android { 264fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 2705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// --- WeakMessageHandler --- 2805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 2905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : 3005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mHandler(handler) { 3105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 3205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 3305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 3405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown sp<MessageHandler> handler = mHandler.promote(); 3505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (handler != NULL) { 3605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown handler->handleMessage(message); 3705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 3805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 3905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 4005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 4105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown// --- Looper --- 4205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 43415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 444fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 454fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownstatic const int EPOLL_SIZE_HINT = 8; 464fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 474fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 484fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 49415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 504fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 51134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 52134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brownstatic pthread_key_t gTLSKey = 0; 53134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown 544fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff BrownLooper::Looper(bool allowNonCallbacks) : 5505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 5605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 574fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int wakeFds[2]; 584fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int result = pipe(wakeFds); 594fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 604fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 614fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mWakeReadPipeFd = wakeFds[0]; 624fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mWakeWritePipeFd = wakeFds[1]; 634fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 644fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 654fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", 664fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown errno); 674fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 684fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 694fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", 704fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown errno); 714fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 72415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 73415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Allocate the epoll instance and register the wake pipe. 74415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 75415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 76415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 774fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown struct epoll_event eventItem; 78134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 794fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown eventItem.events = EPOLLIN; 804fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown eventItem.data.fd = mWakeReadPipeFd; 814fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 824fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", 834fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown errno); 84415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#else 85415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Add the wake pipe to the head of the request list with a null callback. 86415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown struct pollfd requestedFd; 87415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown requestedFd.fd = mWakeReadPipeFd; 88415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown requestedFd.events = POLLIN; 89415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequestedFds.push(requestedFd); 90415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 91415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown Request request; 92415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.fd = mWakeReadPipeFd; 93415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.callback = NULL; 94415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.ident = 0; 95415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.data = NULL; 96415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequests.push(request); 97415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 98415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPolling = false; 99415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mWaiters = 0; 100415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 101415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 102415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_STATISTICS 103415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPendingWakeTime = -1; 104415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPendingWakeCount = 0; 105415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCycles = 0; 106415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCountSum = 0; 107415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeLatencySum = 0; 108415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 109415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledPolls = 0; 110415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollCount = 0; 111415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollLatencySum = 0; 112415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollCount = 0; 113415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollLatencySum = 0; 114415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 1154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1174fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff BrownLooper::~Looper() { 1184fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown close(mWakeReadPipeFd); 1194fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown close(mWakeWritePipeFd); 120415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 1214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown close(mEpollFd); 122415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 1234fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1244fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 125134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brownvoid Looper::initTLSKey() { 126134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 127134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 128134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown} 129134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown 1304fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownvoid Looper::threadDestructor(void *st) { 1314fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown Looper* const self = static_cast<Looper*>(st); 1324fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (self != NULL) { 1334fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown self->decStrong((void*)threadDestructor); 1344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1354fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1364fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1374fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 1384fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 1394fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1404fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (looper != NULL) { 1414fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown looper->incStrong((void*)threadDestructor); 1424fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1434fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 144134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown pthread_setspecific(gTLSKey, looper.get()); 1454fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1464fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (old != NULL) { 1474fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown old->decStrong((void*)threadDestructor); 1484fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1494fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1504fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1514fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownsp<Looper> Looper::getForThread() { 152134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 153134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 1544fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 155134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown return (Looper*)pthread_getspecific(gTLSKey); 1564fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1574fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1584fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownsp<Looper> Looper::prepare(int opts) { 1594fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; 1604fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown sp<Looper> looper = Looper::getForThread(); 1614fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (looper == NULL) { 1624fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown looper = new Looper(allowNonCallbacks); 1634fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown Looper::setForThread(looper); 1644fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1654fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 1664fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGW("Looper already prepared for this thread with a different value for the " 1674fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 1684fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1694fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return looper; 1704fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1714fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1724fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownbool Looper::getAllowNonCallbacks() const { 1734fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return mAllowNonCallbacks; 1744fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 1754fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1764fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 1774fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int result = 0; 1784fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown for (;;) { 1794fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown while (mResponseIndex < mResponses.size()) { 1804fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 18105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown ALooper_callbackFunc callback = response.request.callback; 18205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (!callback) { 18305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int ident = response.request.ident; 18405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int fd = response.request.fd; 18505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int events = response.events; 18605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown void* data = response.request.data; 1874fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 1884fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ pollOnce - returning signalled identifier %d: " 18905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown "fd=%d, events=0x%x, data=%p", 19005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown this, ident, fd, events, data); 1914fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 19205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (outFd != NULL) *outFd = fd; 19305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (outEvents != NULL) *outEvents = events; 19405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (outData != NULL) *outData = data; 19505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown return ident; 1964fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1974fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 1984fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 1994fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (result != 0) { 2004fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 2014fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ pollOnce - returning result %d", this, result); 2024fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 2034fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (outFd != NULL) *outFd = 0; 2044fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (outEvents != NULL) *outEvents = NULL; 2054fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (outData != NULL) *outData = NULL; 2064fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return result; 2074fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 2084fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 2094fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = pollInner(timeoutMillis); 2104fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 2114fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 2124fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 2134fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint Looper::pollInner(int timeoutMillis) { 2144fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 2154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 2164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 217415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 21805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Adjust the timeout based on when the next message is due. 21905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 22005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 221aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 222aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown if (messageTimeoutMillis >= 0 223aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 224aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown timeoutMillis = messageTimeoutMillis; 22505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 22605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#if DEBUG_POLL_AND_WAKE 22705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 22805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown this, mNextMessageUptime - now, timeoutMillis); 22905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#endif 23005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 23105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 23205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Poll. 233415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown int result = ALOOPER_POLL_WAKE; 234415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mResponses.clear(); 235415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mResponseIndex = 0; 236415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 237415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_STATISTICS 238415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 239415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 240415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 241415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 2424fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 2434fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 244415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#else 245415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Wait for wakeAndLock() waiters to run then set mPolling to true. 246415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLock.lock(); 247415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown while (mWaiters != 0) { 248415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mResume.wait(mLock); 249415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 250415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPolling = true; 251415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLock.unlock(); 252415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 253415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown size_t requestedCount = mRequestedFds.size(); 254415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis); 255415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 256415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 25705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Acquire lock. 25805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mLock.lock(); 25905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 26005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Check for poll error. 2614fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (eventCount < 0) { 2627dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown if (errno == EINTR) { 263415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown goto Done; 2644fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 2657dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown LOGW("Poll failed with an unexpected error, errno=%d", errno); 266415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown result = ALOOPER_POLL_ERROR; 267415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown goto Done; 2684fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 2694fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 27005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Check for poll timeout. 2714fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (eventCount == 0) { 2724fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 2734fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ pollOnce - timeout", this); 2744fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 275415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown result = ALOOPER_POLL_TIMEOUT; 276415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown goto Done; 2774fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 2784fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 27905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Handle all events. 2804fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 2814fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 2824fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 283415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 284415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 285960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown for (int i = 0; i < eventCount; i++) { 286960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown int fd = eventItems[i].data.fd; 287960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown uint32_t epollEvents = eventItems[i].events; 288960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (fd == mWakeReadPipeFd) { 289960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (epollEvents & EPOLLIN) { 290415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown awoken(); 2914fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } else { 292960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 293960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown } 294960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown } else { 295960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 296960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (requestIndex >= 0) { 297960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown int events = 0; 298960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; 299960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; 300960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; 301960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; 302415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 303960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown } else { 304960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 305960498728904a1a6ea65171f0cfb3b41187c29aeJeff Brown "no longer registered.", epollEvents, fd); 3064fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 3074fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 3084fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 309415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff BrownDone: ; 310415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#else 311415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown for (size_t i = 0; i < requestedCount; i++) { 312415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown const struct pollfd& requestedFd = mRequestedFds.itemAt(i); 313415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 314415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown short pollEvents = requestedFd.revents; 315415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents) { 316415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (requestedFd.fd == mWakeReadPipeFd) { 317415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLIN) { 318415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown awoken(); 319415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } else { 320415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents); 321415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 322415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } else { 323415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown int events = 0; 324415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT; 325415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT; 326415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR; 327415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP; 328415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID; 329415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown pushResponse(events, mRequests.itemAt(i)); 330415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 331415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (--eventCount == 0) { 332415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown break; 333415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 334415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 335415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 336415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff BrownDone: 337415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // Set mPolling to false and wake up the wakeAndLock() waiters. 338415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPolling = false; 339415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mWaiters != 0) { 340415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mAwake.broadcast(); 341415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 342415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 343415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 344415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_STATISTICS 345415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC); 346415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledPolls += 1; 347415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (timeoutMillis == 0) { 348415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollCount += 1; 349415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollLatencySum += pollEndTime - pollStartTime; 350415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) { 351415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollCount += 1; 352415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime 353415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown - milliseconds_to_nanoseconds(timeoutMillis); 354415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 355415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) { 356415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this, 357415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount, 358415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount); 359415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledPolls = 0; 360415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollCount = 0; 361415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledZeroPollLatencySum = 0; 362415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollCount = 0; 363415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledTimeoutPollLatencySum = 0; 364415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 365415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 3664fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 36705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Invoke pending message callbacks. 36805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mNextMessageUptime = LLONG_MAX; 36905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown while (mMessageEnvelopes.size() != 0) { 37005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 37105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 37205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (messageEnvelope.uptime <= now) { 37305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Remove the envelope from the list. 37405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // We keep a strong reference to the handler until the call to handleMessage 37505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 37605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // we reacquire our lock. 37705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown { // obtain handler 37805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 37905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown Message message = messageEnvelope.message; 38005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mMessageEnvelopes.removeAt(0); 38105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mSendingMessage = true; 38205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mLock.unlock(); 38305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 38405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 38505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 38605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown this, handler.get(), message.what); 38705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#endif 38805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown handler->handleMessage(message); 38905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } // release handler 39005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 39105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mLock.lock(); 39205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mSendingMessage = false; 39305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown result = ALOOPER_POLL_CALLBACK; 39405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } else { 39505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // The last message left at the head of the queue determines the next wakeup time. 39605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mNextMessageUptime = messageEnvelope.uptime; 39705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown break; 39805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 39905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 40005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 40105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Release lock. 40205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mLock.unlock(); 40305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 40405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Invoke all response callbacks. 4054fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 4064fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown const Response& response = mResponses.itemAt(i); 40705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown ALooper_callbackFunc callback = response.request.callback; 40805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (callback) { 40905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int fd = response.request.fd; 41005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int events = response.events; 41105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown void* data = response.request.data; 4124fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 41305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 41405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown this, callback, fd, events, data); 4154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 41605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown int callbackResult = callback(fd, events, data); 4174fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (callbackResult == 0) { 41805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown removeFd(fd); 4194fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4204fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = ALOOPER_POLL_CALLBACK; 4214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4224fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4234fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return result; 4244fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 4254fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 4264fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 4274fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (timeoutMillis <= 0) { 4284fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int result; 4294fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown do { 4304fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 4314fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } while (result == ALOOPER_POLL_CALLBACK); 4324fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return result; 4334fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } else { 4344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 4354fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 4364fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 4374fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown for (;;) { 4384fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 4394fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (result != ALOOPER_POLL_CALLBACK) { 4404fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return result; 4414fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4424fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 443aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 444aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 445aa3855d5836d2a2d83baafdf6e40caf90d3dad1cJeff Brown if (timeoutMillis == 0) { 4464fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return ALOOPER_POLL_TIMEOUT; 4474fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4484fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4494fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4504fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 4514fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 4524fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownvoid Looper::wake() { 4534fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_POLL_AND_WAKE 4544fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ wake", this); 4554fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 4564fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 457415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_STATISTICS 458415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled. 459415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mPendingWakeCount++ == 0) { 460415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC); 461415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 462415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 463415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 4647dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown ssize_t nWrite; 4657dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown do { 4667dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 4677dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown } while (nWrite == -1 && errno == EINTR); 4687dae0e47abb5c1fb852c10b3ba0bc6464dd76e96Jeff Brown 4694fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (nWrite != 1) { 4704fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (errno != EAGAIN) { 4714fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGW("Could not write wake signal, errno=%d", errno); 4724fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4734fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 4744fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 4754fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 476415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownvoid Looper::awoken() { 477415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#if DEBUG_POLL_AND_WAKE 478415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOGD("%p ~ awoken", this); 479415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 480415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 481415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_STATISTICS 482415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mPendingWakeCount == 0) { 483415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOGD("%p ~ awoken: spurious!", this); 484415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } else { 485415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCycles += 1; 486415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCountSum += mPendingWakeCount; 487415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime; 488415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPendingWakeCount = 0; 489415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mPendingWakeTime = -1; 490415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) { 491415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown LOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this, 492415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles, 493415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown float(mSampledWakeCountSum) / mSampledWakeCycles); 494415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCycles = 0; 495415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeCountSum = 0; 496415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mSampledWakeLatencySum = 0; 497415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 498415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 499415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 500415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 501415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown char buffer[16]; 502415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown ssize_t nRead; 503415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown do { 504415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 505415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 506415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown} 507415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 508415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 509415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown Response response; 510415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown response.events = events; 511415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown response.request = request; 512415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mResponses.push(response); 513415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown} 514415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 5154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { 5164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_CALLBACKS 5174fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 5184fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown events, callback, data); 5194fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 5204fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5214fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (! callback) { 5224fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (! mAllowNonCallbacks) { 5234fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 5244fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return -1; 5254fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5264fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5274fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (ident < 0) { 5284fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGE("Invalid attempt to set NULL callback with ident <= 0."); 5294fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return -1; 5304fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5314fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5324fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 533415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 534415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown int epollEvents = 0; 535415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; 536415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; 537415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 5384fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown { // acquire lock 5394fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown AutoMutex _l(mLock); 5404fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5414fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown Request request; 5424fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown request.fd = fd; 5434fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown request.ident = ident; 5444fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown request.callback = callback; 5454fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown request.data = data; 5464fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5474fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown struct epoll_event eventItem; 548134b4ae90103a7b205cd84d0491a4868cb102a7cJeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 5494fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown eventItem.events = epollEvents; 5504fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown eventItem.data.fd = fd; 5514fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5524fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 5534fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (requestIndex < 0) { 5544fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 5554fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (epollResult < 0) { 5564fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); 5574fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return -1; 5584fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5594fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mRequests.add(fd, request); 5604fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } else { 5614fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 5624fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (epollResult < 0) { 5634fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); 5644fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return -1; 5654fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5664fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mRequests.replaceValueAt(requestIndex, request); 5674fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 5684fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } // release lock 569415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#else 570415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown int pollEvents = 0; 571415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN; 572415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT; 573415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 574415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown wakeAndLock(); // acquire lock 575415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 576415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown struct pollfd requestedFd; 577415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown requestedFd.fd = fd; 578415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown requestedFd.events = pollEvents; 579415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 580415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown Request request; 581415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.fd = fd; 582415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.ident = ident; 583415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.callback = callback; 584415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown request.data = data; 585415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown ssize_t index = getRequestIndexLocked(fd); 586415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (index < 0) { 587415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequestedFds.push(requestedFd); 588415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequests.push(request); 589415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } else { 590415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequestedFds.replaceAt(requestedFd, size_t(index)); 591415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequests.replaceAt(request, size_t(index)); 592415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 593415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 594415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLock.unlock(); // release lock 595415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 5964fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return 1; 5974fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 5984fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 5994fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brownint Looper::removeFd(int fd) { 6004fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#if DEBUG_CALLBACKS 6014fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGD("%p ~ removeFd - fd=%d", this, fd); 6024fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown#endif 6034fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 604415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifdef LOOPER_USES_EPOLL 6054fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown { // acquire lock 6064fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown AutoMutex _l(mLock); 6074fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 6084fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (requestIndex < 0) { 6094fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return 0; 6104fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 6114fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 6124fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 6134fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown if (epollResult < 0) { 6144fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown LOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); 6154fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return -1; 6164fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown } 6174fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 6184fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown mRequests.removeItemsAt(requestIndex); 619415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } // release lock 6204fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown return 1; 621415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#else 622415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown wakeAndLock(); // acquire lock 623415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 624415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown ssize_t index = getRequestIndexLocked(fd); 625415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (index >= 0) { 626415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequestedFds.removeAt(size_t(index)); 627415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mRequests.removeAt(size_t(index)); 628415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 629415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 630415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLock.unlock(); // release lock 631415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown return index >= 0; 632415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 6334fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} 6344fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown 635415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#ifndef LOOPER_USES_EPOLL 636415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownssize_t Looper::getRequestIndexLocked(int fd) { 637415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown size_t requestCount = mRequestedFds.size(); 638415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 639415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown for (size_t i = 0; i < requestCount; i++) { 640415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mRequestedFds.itemAt(i).fd == fd) { 641415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown return i; 642415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 643415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 644415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 645415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown return -1; 646415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown} 647415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 648415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brownvoid Looper::wakeAndLock() { 649415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mLock.lock(); 650415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 651415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mWaiters += 1; 652415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown while (mPolling) { 653415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown wake(); 654415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mAwake.wait(mLock); 655415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 656415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 657415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mWaiters -= 1; 658415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown if (mWaiters == 0) { 659415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown mResume.signal(); 660415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown } 661415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown} 662415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown#endif 663415d8c38199e258dfce92cdb0c69e056b3b51ef8Jeff Brown 66405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 6652352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 6662352b978a3c94cd88f41d0d908f961333fdac1e9Jeff Brown sendMessageAtTime(now, handler, message); 66705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 66805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 66905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 67005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown const Message& message) { 67105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 67205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 67305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 67405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 67505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 67605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown const Message& message) { 67705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#if DEBUG_CALLBACKS 67805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 67905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown this, uptime, handler.get(), message.what); 68005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#endif 68105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 68205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown size_t i = 0; 68305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown { // acquire lock 68405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown AutoMutex _l(mLock); 68505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 68605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown size_t messageCount = mMessageEnvelopes.size(); 68705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 68805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown i += 1; 68905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 69005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 69105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 69205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 69305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 69405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 69505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // the call to wake() because the next thing the Looper will do after processing 69605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 69705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // not even matter whether this code is running on the Looper thread. 69805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (mSendingMessage) { 69905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown return; 70005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 70105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } // release lock 70205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 70305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown // Wake the poll loop only when we enqueue a new message at the head. 70405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (i == 0) { 70505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown wake(); 70605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 70705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 70805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 70905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 71005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#if DEBUG_CALLBACKS 71105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 71205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#endif 71305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 71405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown { // acquire lock 71505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown AutoMutex _l(mLock); 71605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 71705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 71805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 71905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (messageEnvelope.handler == handler) { 72005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mMessageEnvelopes.removeAt(i); 72105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 72205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 72305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } // release lock 72405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 72505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 72605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 72705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#if DEBUG_CALLBACKS 72805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown LOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 72905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown#endif 73005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 73105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown { // acquire lock 73205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown AutoMutex _l(mLock); 73305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 73405dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 73505dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 73605dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown if (messageEnvelope.handler == handler 73705dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown && messageEnvelope.message.what == what) { 73805dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown mMessageEnvelopes.removeAt(i); 73905dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 74005dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } 74105dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown } // release lock 74205dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown} 74305dc66ada6b61a6bdf806ffaa62617ac5394695dJeff Brown 7444fe6c3e51be77e35f40872cdbca6c80f8f8b7ecbJeff Brown} // namespace android 745