Looper.cpp revision e6f43ddce78d6846af12550ff9193c5c6fe5844b
159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// 259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Copyright 2010 The Android Open Source Project 359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// 459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// A looper implementation based on epoll(). 559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// 659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#define LOG_TAG "Looper" 759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown//#define LOG_NDEBUG 0 959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 1059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Debugs poll and wake interactions. 1159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#define DEBUG_POLL_AND_WAKE 0 1259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 1359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Debugs callback registration and invocation. 1459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#define DEBUG_CALLBACKS 0 1559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 1659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#include <cutils/log.h> 1759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#include <utils/Looper.h> 1859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#include <utils/Timers.h> 1959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 2059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#include <unistd.h> 2159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#include <fcntl.h> 2280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#include <limits.h> 2359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 2459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 2559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownnamespace android { 2659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 2780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown// --- WeakMessageHandler --- 2880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 2980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) : 3080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mHandler(handler) { 3180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 3280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 3380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 3480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sp<MessageHandler> handler = mHandler.promote(); 3580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (handler != NULL) { 3680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown handler->handleMessage(message); 3780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 3880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 3980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 4080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 4180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown// --- Looper --- 4280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 4354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 4459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 4559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownstatic const int EPOLL_SIZE_HINT = 8; 4659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 4759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 4859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 4954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 5059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 5161a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 5261a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownstatic pthread_key_t gTLSKey = 0; 5361a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown 5459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff BrownLooper::Looper(bool allowNonCallbacks) : 5580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 5680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 5759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int wakeFds[2]; 5859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = pipe(wakeFds); 5959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 6059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 6159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mWakeReadPipeFd = wakeFds[0]; 6259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mWakeWritePipeFd = wakeFds[1]; 6359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 6459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 6559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", 6659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 6759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 6859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 6959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", 7059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 7159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 7254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 7354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Allocate the epoll instance and register the wake pipe. 7454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 7554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 7654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 7759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItem; 7861a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 7959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.events = EPOLLIN; 8059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.data.fd = mWakeReadPipeFd; 8159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 8259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", 8359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 8454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 8554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Add the wake pipe to the head of the request list with a null callback. 8654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown struct pollfd requestedFd; 8754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.fd = mWakeReadPipeFd; 8854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.events = POLLIN; 8954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.push(requestedFd); 9054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 9154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Request request; 9254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.fd = mWakeReadPipeFd; 9354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.callback = NULL; 9454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.ident = 0; 9554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.data = NULL; 9654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.push(request); 9754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 9854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPolling = false; 9954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mWaiters = 0; 10054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 10154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 10254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 10354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeTime = -1; 10454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeCount = 0; 10554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCycles = 0; 10654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCountSum = 0; 10754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeLatencySum = 0; 10854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 10954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledPolls = 0; 11054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollCount = 0; 11154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollLatencySum = 0; 11254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollCount = 0; 11354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollLatencySum = 0; 11454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 11559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 11659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 11759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff BrownLooper::~Looper() { 11859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mWakeReadPipeFd); 11959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mWakeWritePipeFd); 12054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 12159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mEpollFd); 12254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 12359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 12459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 12561a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownvoid Looper::initTLSKey() { 12661a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 12761a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 12861a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown} 12961a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown 13059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::threadDestructor(void *st) { 13159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Looper* const self = static_cast<Looper*>(st); 13259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (self != NULL) { 13359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown self->decStrong((void*)threadDestructor); 13459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 13559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 13659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 13759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 13859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 13959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 14059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper != NULL) { 14159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown looper->incStrong((void*)threadDestructor); 14259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 14359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 14461a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown pthread_setspecific(gTLSKey, looper.get()); 14559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 14659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (old != NULL) { 14759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown old->decStrong((void*)threadDestructor); 14859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 14959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 15059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 15159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownsp<Looper> Looper::getForThread() { 15261a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 15361a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 15459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 15561a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown return (Looper*)pthread_getspecific(gTLSKey); 15659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 15759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 15859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownsp<Looper> Looper::prepare(int opts) { 15959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; 16059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown sp<Looper> looper = Looper::getForThread(); 16159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper == NULL) { 16259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown looper = new Looper(allowNonCallbacks); 16359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Looper::setForThread(looper); 16459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 16559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 16632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Looper already prepared for this thread with a different value for the " 16759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 16859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 16959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return looper; 17059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 17159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 17259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownbool Looper::getAllowNonCallbacks() const { 17359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return mAllowNonCallbacks; 17459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 17559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 17659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 17759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = 0; 17859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (;;) { 17959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown while (mResponseIndex < mResponses.size()) { 18059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 18180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown ALooper_callbackFunc callback = response.request.callback; 18280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (!callback) { 18380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int ident = response.request.ident; 18480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int fd = response.request.fd; 18580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int events = response.events; 18680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown void* data = response.request.data; 18759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 1889d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - returning signalled identifier %d: " 18980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown "fd=%d, events=0x%x, data=%p", 19080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, ident, fd, events, data); 19159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 19280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outFd != NULL) *outFd = fd; 19380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outEvents != NULL) *outEvents = events; 19480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outData != NULL) *outData = data; 19580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown return ident; 19659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 19759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 19859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 19959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (result != 0) { 20059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2019d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - returning result %d", this, result); 20259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 20359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (outFd != NULL) *outFd = 0; 20459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (outEvents != NULL) *outEvents = NULL; 20559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (outData != NULL) *outData = NULL; 20659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 20759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 20859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 20959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = pollInner(timeoutMillis); 21059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 21159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 21259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 21359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollInner(int timeoutMillis) { 21459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2159d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 21659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 21754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 21880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Adjust the timeout based on when the next message is due. 21980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 22080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 221c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 222c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown if (messageTimeoutMillis >= 0 223c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 224c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown timeoutMillis = messageTimeoutMillis; 22580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 22680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE 2279d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 22880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, mNextMessageUptime - now, timeoutMillis); 22980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 23080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 23180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 23280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Poll. 23354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int result = ALOOPER_POLL_WAKE; 23454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.clear(); 23554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponseIndex = 0; 23654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 23754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 23854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 23954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 24054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 24154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 24259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 24359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 24454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 24554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Wait for wakeAndLock() waiters to run then set mPolling to true. 24654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.lock(); 24754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown while (mWaiters != 0) { 24854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResume.wait(mLock); 24954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 25054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPolling = true; 25154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); 25254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 25354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown size_t requestedCount = mRequestedFds.size(); 25454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis); 25554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 25654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 25780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Acquire lock. 25880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 25980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 26080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll error. 26159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount < 0) { 262f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown if (errno == EINTR) { 26354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 26459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 26532397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Poll failed with an unexpected error, errno=%d", errno); 26654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_ERROR; 26754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 26859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 26959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 27080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll timeout. 27159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount == 0) { 27259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2739d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - timeout", this); 27459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 27554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_TIMEOUT; 27654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 27759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 27859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 27980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Handle all events. 28059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2819d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 28259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 28354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 28454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 285ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown for (int i = 0; i < eventCount; i++) { 286ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int fd = eventItems[i].data.fd; 287ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown uint32_t epollEvents = eventItems[i].events; 288ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (fd == mWakeReadPipeFd) { 289ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) { 29054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown awoken(); 29159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 29232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 293ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } 294ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 295ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 296ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (requestIndex >= 0) { 297ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int events = 0; 298ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; 299ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; 300ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; 301ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; 30254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 303ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 30432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 305ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown "no longer registered.", epollEvents, fd); 30659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 30759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 30859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 30954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff BrownDone: ; 31054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 31154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown for (size_t i = 0; i < requestedCount; i++) { 31254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown const struct pollfd& requestedFd = mRequestedFds.itemAt(i); 31354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 31454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown short pollEvents = requestedFd.revents; 31554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents) { 31654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (requestedFd.fd == mWakeReadPipeFd) { 31754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLIN) { 31854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown awoken(); 31954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 32032397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents); 32154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 32254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 32354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int events = 0; 32454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT; 32554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT; 32654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR; 32754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP; 32854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID; 32954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown pushResponse(events, mRequests.itemAt(i)); 33054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (--eventCount == 0) { 33254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown break; 33354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff BrownDone: 33754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Set mPolling to false and wake up the wakeAndLock() waiters. 33854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPolling = false; 33954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mWaiters != 0) { 34054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mAwake.broadcast(); 34154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 34254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 34354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 34454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 34554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC); 34654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledPolls += 1; 34754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (timeoutMillis == 0) { 34854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollCount += 1; 34954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollLatencySum += pollEndTime - pollStartTime; 35054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) { 35154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollCount += 1; 35254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime 35354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown - milliseconds_to_nanoseconds(timeoutMillis); 35454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 35554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) { 3569d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this, 35754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount, 35854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount); 35954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledPolls = 0; 36054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollCount = 0; 36154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollLatencySum = 0; 36254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollCount = 0; 36354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollLatencySum = 0; 36454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 36554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 36659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 36780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke pending message callbacks. 36880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = LLONG_MAX; 36980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (mMessageEnvelopes.size() != 0) { 37080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 37180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 37280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.uptime <= now) { 37380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Remove the envelope from the list. 37480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // We keep a strong reference to the handler until the call to handleMessage 37580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 37680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // we reacquire our lock. 37780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // obtain handler 37880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 37980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown Message message = messageEnvelope.message; 38080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(0); 38180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = true; 38280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 38380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 38480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 3859d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 38680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, handler.get(), message.what); 38780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 38880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown handler->handleMessage(message); 38980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release handler 39080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 39180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 39280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = false; 39380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown result = ALOOPER_POLL_CALLBACK; 39480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } else { 39580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // The last message left at the head of the queue determines the next wakeup time. 39680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = messageEnvelope.uptime; 39780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown break; 39880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 39980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 40080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 40180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Release lock. 40280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 40380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 40480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke all response callbacks. 40559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 40659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown const Response& response = mResponses.itemAt(i); 40780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown ALooper_callbackFunc callback = response.request.callback; 40880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (callback) { 40980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int fd = response.request.fd; 41080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int events = response.events; 41180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown void* data = response.request.data; 41259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 4139d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 41480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, callback, fd, events, data); 41559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 41680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int callbackResult = callback(fd, events, data); 41759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (callbackResult == 0) { 41880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown removeFd(fd); 41959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = ALOOPER_POLL_CALLBACK; 42159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 42459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 42559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 42659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 42759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (timeoutMillis <= 0) { 42859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result; 42959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown do { 43059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 43159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } while (result == ALOOPER_POLL_CALLBACK); 43259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 43359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 43459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 43559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 43659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 43759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (;;) { 43859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 43959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (result != ALOOPER_POLL_CALLBACK) { 44059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 44159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 44259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 443c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 444c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 445c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown if (timeoutMillis == 0) { 44659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return ALOOPER_POLL_TIMEOUT; 44759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 44859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 44959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 45159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 45259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::wake() { 45359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 4549d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ wake", this); 45559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 45659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 45754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 45854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled. 45954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mPendingWakeCount++ == 0) { 46054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC); 46154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 46254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 46354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 464f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown ssize_t nWrite; 465f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown do { 466f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 467f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown } while (nWrite == -1 && errno == EINTR); 468f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown 46959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (nWrite != 1) { 47059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (errno != EAGAIN) { 47132397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Could not write wake signal, errno=%d", errno); 47259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 47359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 47459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 47559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 47654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::awoken() { 47754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#if DEBUG_POLL_AND_WAKE 4789d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ awoken", this); 47954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 48054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 48154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 48254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mPendingWakeCount == 0) { 4839d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ awoken: spurious!", this); 48454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 48554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCycles += 1; 48654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCountSum += mPendingWakeCount; 48754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime; 48854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeCount = 0; 48954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeTime = -1; 49054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) { 4919d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this, 49254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles, 49354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown float(mSampledWakeCountSum) / mSampledWakeCycles); 49454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCycles = 0; 49554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCountSum = 0; 49654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeLatencySum = 0; 49754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 49854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 49954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 50054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 50154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown char buffer[16]; 50254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t nRead; 50354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown do { 50454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 50554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 50654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 50754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 50854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 50954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Response response; 51054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.events = events; 51154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.request = request; 51254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.push(response); 51354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 51454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 51559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { 51659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 5179d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 51859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown events, callback, data); 51959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 52059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 52159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (! callback) { 52259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (! mAllowNonCallbacks) { 523e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 52459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 52559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 52659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 52759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (ident < 0) { 528e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Invalid attempt to set NULL callback with ident <= 0."); 52959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 53059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 53159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 53259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 53354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 53454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int epollEvents = 0; 53554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; 53654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; 53754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 53859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 53959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 54059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 54159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Request request; 54259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.fd = fd; 54359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.ident = ident; 54459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.callback = callback; 54559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.data = data; 54659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 54759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItem; 54861a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 54959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.events = epollEvents; 55059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.data.fd = fd; 55159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 55259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 55359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 55459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 55559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 556e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); 55759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 55859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 55959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.add(fd, request); 56059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 56159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 56259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 563e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); 56459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 56559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 56659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.replaceValueAt(requestIndex, request); 56759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 56859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } // release lock 56954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 57054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int pollEvents = 0; 57154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN; 57254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT; 57354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 57454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wakeAndLock(); // acquire lock 57554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 57654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown struct pollfd requestedFd; 57754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.fd = fd; 57854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.events = pollEvents; 57954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 58054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Request request; 58154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.fd = fd; 58254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.ident = ident; 58354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.callback = callback; 58454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.data = data; 58554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t index = getRequestIndexLocked(fd); 58654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (index < 0) { 58754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.push(requestedFd); 58854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.push(request); 58954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 59054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.replaceAt(requestedFd, size_t(index)); 59154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.replaceAt(request, size_t(index)); 59254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 59354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 59454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); // release lock 59554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 59659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 59759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 59859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 59959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::removeFd(int fd) { 60059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 6019d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeFd - fd=%d", this, fd); 60259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 60359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 60454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 60559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 60659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 60759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 60859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 60959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 0; 61059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 61159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 61259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 61359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 614e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); 61559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 61659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 61759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 61859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.removeItemsAt(requestIndex); 61954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } // release lock 62059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 62154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 62254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wakeAndLock(); // acquire lock 62354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 62454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t index = getRequestIndexLocked(fd); 62554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (index >= 0) { 62654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.removeAt(size_t(index)); 62754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.removeAt(size_t(index)); 62854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 62954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 63054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); // release lock 63154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return index >= 0; 63254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 63359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 63459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 63554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifndef LOOPER_USES_EPOLL 63654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownssize_t Looper::getRequestIndexLocked(int fd) { 63754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown size_t requestCount = mRequestedFds.size(); 63854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 63954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown for (size_t i = 0; i < requestCount; i++) { 64054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mRequestedFds.itemAt(i).fd == fd) { 64154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return i; 64254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 64354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 64454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 64554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return -1; 64654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 64754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 64854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::wakeAndLock() { 64954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.lock(); 65054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 65154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mWaiters += 1; 65254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown while (mPolling) { 65354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wake(); 65454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mAwake.wait(mLock); 65554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 65654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 65754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mWaiters -= 1; 65854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mWaiters == 0) { 65954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResume.signal(); 66054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 66154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 66254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 66354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 66480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 6654815f2a6ada7941680b29581d5cf5a5ed168f618Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 6664815f2a6ada7941680b29581d5cf5a5ed168f618Jeff Brown sendMessageAtTime(now, handler, message); 66780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 66880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 66980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 67080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 67180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 67280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 67380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 67480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 67580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 67680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 67780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 6789d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 67980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, uptime, handler.get(), message.what); 68080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 68180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 68280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t i = 0; 68380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 68480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 68580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 68680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t messageCount = mMessageEnvelopes.size(); 68780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 68880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown i += 1; 68980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 69080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 69180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 69280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 69380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 69480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 69580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // the call to wake() because the next thing the Looper will do after processing 69680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 69780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // not even matter whether this code is running on the Looper thread. 69880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (mSendingMessage) { 69980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown return; 70080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 70180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 70280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 70380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Wake the poll loop only when we enqueue a new message at the head. 70480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (i == 0) { 70580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown wake(); 70680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 70780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 70880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 70980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 71080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 7119d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 71280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 71380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 71480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 71580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 71680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 71780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 71880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 71980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler) { 72080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 72180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 72280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 72380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 72480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 72580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 72680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 72780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 7289d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 72980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 73080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 73180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 73280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 73380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 73480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 73580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 73680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler 73780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown && messageEnvelope.message.what == what) { 73880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 73980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 74080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 74180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 74280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 74380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 74459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} // namespace android 745