Looper.cpp revision 80f3e7cc1506bbb4bec458e15629805a7c1df7ee
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) { 16659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGW("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 18859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%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 20159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%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 21559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%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); 22180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (mNextMessageUptime <= now) { 22280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown timeoutMillis = 0; 22380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } else { 22480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown uint64_t delay = (mNextMessageUptime - now + 999999LL) / 1000000LL; 22580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (delay < INT_MAX 22680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown && (timeoutMillis < 0 || int(delay) < timeoutMillis)) { 22780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown timeoutMillis = int(delay); 22880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 22980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 23080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE 23180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 23280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, mNextMessageUptime - now, timeoutMillis); 23380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 23480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 23580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 23680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Poll. 23754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int result = ALOOPER_POLL_WAKE; 23854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.clear(); 23954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponseIndex = 0; 24054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 24154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 24254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC); 24354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 24454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 24554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 24659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 24759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 24854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 24954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Wait for wakeAndLock() waiters to run then set mPolling to true. 25054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.lock(); 25154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown while (mWaiters != 0) { 25254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResume.wait(mLock); 25354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 25454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPolling = true; 25554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); 25654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 25754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown size_t requestedCount = mRequestedFds.size(); 25854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis); 25954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 26054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 26180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Acquire lock. 26280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 26380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 26480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll error. 26559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount < 0) { 266f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown if (errno == EINTR) { 26754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 26859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 269f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown LOGW("Poll failed with an unexpected error, errno=%d", errno); 27054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_ERROR; 27154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 27259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 27359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 27480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll timeout. 27559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount == 0) { 27659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 27759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%p ~ pollOnce - timeout", this); 27859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 27954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_TIMEOUT; 28054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 28159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 28259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 28380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Handle all events. 28459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 28559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 28659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 28754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 28854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 289ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown for (int i = 0; i < eventCount; i++) { 290ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int fd = eventItems[i].data.fd; 291ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown uint32_t epollEvents = eventItems[i].events; 292ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (fd == mWakeReadPipeFd) { 293ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) { 29454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown awoken(); 29559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 296ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 297ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } 298ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 299ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 300ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (requestIndex >= 0) { 301ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int events = 0; 302ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; 303ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; 304ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; 305ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; 30654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 307ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 308ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 309ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown "no longer registered.", epollEvents, fd); 31059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 31159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 31259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 31354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff BrownDone: ; 31454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 31554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown for (size_t i = 0; i < requestedCount; i++) { 31654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown const struct pollfd& requestedFd = mRequestedFds.itemAt(i); 31754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 31854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown short pollEvents = requestedFd.revents; 31954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents) { 32054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (requestedFd.fd == mWakeReadPipeFd) { 32154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLIN) { 32254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown awoken(); 32354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 32454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents); 32554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 32654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 32754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int events = 0; 32854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT; 32954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT; 33054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR; 33154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP; 33254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID; 33354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown pushResponse(events, mRequests.itemAt(i)); 33454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (--eventCount == 0) { 33654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown break; 33754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 33954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 34054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff BrownDone: 34154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Set mPolling to false and wake up the wakeAndLock() waiters. 34254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPolling = false; 34354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mWaiters != 0) { 34454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mAwake.broadcast(); 34554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 34654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 34754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 34854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 34954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC); 35054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledPolls += 1; 35154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (timeoutMillis == 0) { 35254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollCount += 1; 35354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollLatencySum += pollEndTime - pollStartTime; 35454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) { 35554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollCount += 1; 35654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime 35754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown - milliseconds_to_nanoseconds(timeoutMillis); 35854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 35954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) { 36054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this, 36154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount, 36254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount); 36354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledPolls = 0; 36454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollCount = 0; 36554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledZeroPollLatencySum = 0; 36654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollCount = 0; 36754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledTimeoutPollLatencySum = 0; 36854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 36954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 37059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 37180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke pending message callbacks. 37280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = LLONG_MAX; 37380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (mMessageEnvelopes.size() != 0) { 37480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 37580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 37680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.uptime <= now) { 37780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Remove the envelope from the list. 37880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // We keep a strong reference to the handler until the call to handleMessage 37980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 38080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // we reacquire our lock. 38180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // obtain handler 38280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 38380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown Message message = messageEnvelope.message; 38480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(0); 38580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = true; 38680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 38780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 38880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 38980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 39080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, handler.get(), message.what); 39180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 39280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown handler->handleMessage(message); 39380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release handler 39480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 39580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 39680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = false; 39780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown result = ALOOPER_POLL_CALLBACK; 39880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } else { 39980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // The last message left at the head of the queue determines the next wakeup time. 40080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = messageEnvelope.uptime; 40180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown break; 40280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 40380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 40480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 40580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Release lock. 40680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 40780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 40880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke all response callbacks. 40959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 41059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown const Response& response = mResponses.itemAt(i); 41180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown ALooper_callbackFunc callback = response.request.callback; 41280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (callback) { 41380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int fd = response.request.fd; 41480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int events = response.events; 41580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown void* data = response.request.data; 41659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 41780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 41880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, callback, fd, events, data); 41959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 42080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int callbackResult = callback(fd, events, data); 42159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (callbackResult == 0) { 42280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown removeFd(fd); 42359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = ALOOPER_POLL_CALLBACK; 42559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 42759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 42859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 42959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 43059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 43159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (timeoutMillis <= 0) { 43259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result; 43359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown do { 43459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 43559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } while (result == ALOOPER_POLL_CALLBACK); 43659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 43759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 43859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 43959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 44059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 44159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (;;) { 44259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 44359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (result != ALOOPER_POLL_CALLBACK) { 44459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 44559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 44659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 44759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC); 44859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (timeoutNanos <= 0) { 44959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return ALOOPER_POLL_TIMEOUT; 45059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 45259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL)); 45359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 45659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 45759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::wake() { 45859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 45959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%p ~ wake", this); 46059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 46159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 46254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 46354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled. 46454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mPendingWakeCount++ == 0) { 46554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC); 46654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 46754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 46854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 469f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown ssize_t nWrite; 470f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown do { 471f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 472f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown } while (nWrite == -1 && errno == EINTR); 473f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown 47459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (nWrite != 1) { 47559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (errno != EAGAIN) { 47659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGW("Could not write wake signal, errno=%d", errno); 47759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 47859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 47959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 48059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 48154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::awoken() { 48254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#if DEBUG_POLL_AND_WAKE 48354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOGD("%p ~ awoken", this); 48454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 48554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 48654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_STATISTICS 48754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mPendingWakeCount == 0) { 48854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOGD("%p ~ awoken: spurious!", this); 48954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 49054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCycles += 1; 49154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCountSum += mPendingWakeCount; 49254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime; 49354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeCount = 0; 49454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mPendingWakeTime = -1; 49554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) { 49654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this, 49754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles, 49854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown float(mSampledWakeCountSum) / mSampledWakeCycles); 49954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCycles = 0; 50054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeCountSum = 0; 50154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mSampledWakeLatencySum = 0; 50254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 50354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 50454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 50554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 50654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown char buffer[16]; 50754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t nRead; 50854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown do { 50954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 51054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 51154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 51254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 51354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 51454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Response response; 51554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.events = events; 51654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.request = request; 51754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.push(response); 51854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 51954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 52059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { 52159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 52259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 52359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown events, callback, data); 52459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 52559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 52659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (! callback) { 52759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (! mAllowNonCallbacks) { 52859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 52959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 53059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 53159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 53259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (ident < 0) { 53359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGE("Invalid attempt to set NULL callback with ident <= 0."); 53459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 53559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 53659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 53759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 53854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 53954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int epollEvents = 0; 54054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; 54154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; 54254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 54359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 54459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 54559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 54659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Request request; 54759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.fd = fd; 54859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.ident = ident; 54959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.callback = callback; 55059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.data = data; 55159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 55259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItem; 55361a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 55459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.events = epollEvents; 55559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.data.fd = fd; 55659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 55759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 55859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 55959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 56059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 56159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); 56259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 56359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 56459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.add(fd, request); 56559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 56659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 56759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 56859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); 56959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 57059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 57159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.replaceValueAt(requestIndex, request); 57259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 57359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } // release lock 57454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 57554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int pollEvents = 0; 57654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN; 57754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT; 57854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 57954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wakeAndLock(); // acquire lock 58054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 58154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown struct pollfd requestedFd; 58254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.fd = fd; 58354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown requestedFd.events = pollEvents; 58454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 58554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Request request; 58654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.fd = fd; 58754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.ident = ident; 58854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.callback = callback; 58954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown request.data = data; 59054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t index = getRequestIndexLocked(fd); 59154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (index < 0) { 59254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.push(requestedFd); 59354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.push(request); 59454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } else { 59554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.replaceAt(requestedFd, size_t(index)); 59654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.replaceAt(request, size_t(index)); 59754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 59854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 59954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); // release lock 60054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 60159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 60259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 60359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 60459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::removeFd(int fd) { 60559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 60659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGD("%p ~ removeFd - fd=%d", this, fd); 60759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 60859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 60954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifdef LOOPER_USES_EPOLL 61059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 61159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 61259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 61359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 61459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 0; 61559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 61659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 61759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 61859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 61959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); 62059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 62159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 62259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 62359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.removeItemsAt(requestIndex); 62454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } // release lock 62559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 62654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#else 62754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wakeAndLock(); // acquire lock 62854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 62954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t index = getRequestIndexLocked(fd); 63054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (index >= 0) { 63154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequestedFds.removeAt(size_t(index)); 63254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mRequests.removeAt(size_t(index)); 63354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 63454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 63554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.unlock(); // release lock 63654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return index >= 0; 63754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 63859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 63959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 64054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#ifndef LOOPER_USES_EPOLL 64154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownssize_t Looper::getRequestIndexLocked(int fd) { 64254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown size_t requestCount = mRequestedFds.size(); 64354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 64454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown for (size_t i = 0; i < requestCount; i++) { 64554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mRequestedFds.itemAt(i).fd == fd) { 64654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return i; 64754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 64854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 64954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 65054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown return -1; 65154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 65254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 65354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::wakeAndLock() { 65454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mLock.lock(); 65554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 65654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mWaiters += 1; 65754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown while (mPolling) { 65854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown wake(); 65954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mAwake.wait(mLock); 66054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 66154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 66254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mWaiters -= 1; 66354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (mWaiters == 0) { 66454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResume.signal(); 66554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } 66654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 66754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 66854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 66980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 67080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sendMessageAtTime(LLONG_MIN, handler, message); 67180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 67280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 67380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 67480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 67580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 67680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 67780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 67880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 67980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 68080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 68180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 68280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 68380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, uptime, handler.get(), message.what); 68480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 68580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 68680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t i = 0; 68780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 68880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 68980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 69080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t messageCount = mMessageEnvelopes.size(); 69180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 69280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown i += 1; 69380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 69480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 69580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 69680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 69780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 69880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 69980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // the call to wake() because the next thing the Looper will do after processing 70080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 70180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // not even matter whether this code is running on the Looper thread. 70280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (mSendingMessage) { 70380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown return; 70480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 70580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 70680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 70780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Wake the poll loop only when we enqueue a new message at the head. 70880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (i == 0) { 70980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown wake(); 71080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 71180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 71280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 71380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 71480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 71580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 71680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 71780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 71880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 71980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 72080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 72180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 72280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 72380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler) { 72480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 72580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 72680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 72780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 72880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 72980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 73080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 73180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 73280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown LOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 73380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 73480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 73580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 73680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 73780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 73880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 73980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 74080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler 74180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown && messageEnvelope.message.what == what) { 74280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 74380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 74480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 74580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 74680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 74780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 74859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} // namespace android 749