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 33af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff BrownWeakMessageHandler::~WeakMessageHandler() { 34af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown} 35af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 3680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) { 3780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sp<MessageHandler> handler = mHandler.promote(); 3880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (handler != NULL) { 3980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown handler->handleMessage(message); 4080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 4180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 4280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 4380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 44af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown// --- SimpleLooperCallback --- 45af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 46af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff BrownSimpleLooperCallback::SimpleLooperCallback(ALooper_callbackFunc callback) : 47af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown mCallback(callback) { 48af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown} 49af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 50af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff BrownSimpleLooperCallback::~SimpleLooperCallback() { 51af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown} 52af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 53af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brownint SimpleLooperCallback::handleEvent(int fd, int events, void* data) { 54af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown return mCallback(fd, events, data); 55af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown} 56af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 57af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 5880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown// --- Looper --- 5980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 6059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Hint for number of file descriptors to be associated with the epoll instance. 6159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownstatic const int EPOLL_SIZE_HINT = 8; 6259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 6359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration. 6459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownstatic const int EPOLL_MAX_EVENTS = 16; 6559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 6661a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT; 6761a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownstatic pthread_key_t gTLSKey = 0; 6861a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown 6959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff BrownLooper::Looper(bool allowNonCallbacks) : 7080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false), 7180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mResponseIndex(0), mNextMessageUptime(LLONG_MAX) { 7259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int wakeFds[2]; 7359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = pipe(wakeFds); 7459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno); 7559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 7659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mWakeReadPipeFd = wakeFds[0]; 7759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mWakeWritePipeFd = wakeFds[1]; 7859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 7959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK); 8059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d", 8159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 8259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 8359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK); 8459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d", 8559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 8659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 8754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown // Allocate the epoll instance and register the wake pipe. 8854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mEpollFd = epoll_create(EPOLL_SIZE_HINT); 8954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno); 9054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 9159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItem; 9261a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 9359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.events = EPOLLIN; 9459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.data.fd = mWakeReadPipeFd; 9559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem); 9659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d", 9759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown errno); 9859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 9959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 10059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff BrownLooper::~Looper() { 10159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mWakeReadPipeFd); 10259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mWakeWritePipeFd); 10359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown close(mEpollFd); 10459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 10559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 10661a25b249066baed0fdab0411f44a2c6b7292766Jeff Brownvoid Looper::initTLSKey() { 10761a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown int result = pthread_key_create(& gTLSKey, threadDestructor); 10861a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key."); 10961a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown} 11061a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown 11159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::threadDestructor(void *st) { 11259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Looper* const self = static_cast<Looper*>(st); 11359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (self != NULL) { 11459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown self->decStrong((void*)threadDestructor); 11559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 11659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 11759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 11859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::setForThread(const sp<Looper>& looper) { 11959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown sp<Looper> old = getForThread(); // also has side-effect of initializing TLS 12059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 12159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper != NULL) { 12259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown looper->incStrong((void*)threadDestructor); 12359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 12459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 12561a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown pthread_setspecific(gTLSKey, looper.get()); 12659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 12759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (old != NULL) { 12859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown old->decStrong((void*)threadDestructor); 12959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 13059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 13159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 13259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownsp<Looper> Looper::getForThread() { 13361a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown int result = pthread_once(& gTLSOnce, initTLSKey); 13461a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed"); 13559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 13661a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown return (Looper*)pthread_getspecific(gTLSKey); 13759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 13859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 13959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownsp<Looper> Looper::prepare(int opts) { 14059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS; 14159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown sp<Looper> looper = Looper::getForThread(); 14259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper == NULL) { 14359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown looper = new Looper(allowNonCallbacks); 14459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Looper::setForThread(looper); 14559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 14659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (looper->getAllowNonCallbacks() != allowNonCallbacks) { 14732397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Looper already prepared for this thread with a different value for the " 14859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option."); 14959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 15059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return looper; 15159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 15259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 15359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownbool Looper::getAllowNonCallbacks() const { 15459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return mAllowNonCallbacks; 15559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 15659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 15759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 15859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = 0; 15959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (;;) { 16059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown while (mResponseIndex < mResponses.size()) { 16159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown const Response& response = mResponses.itemAt(mResponseIndex++); 162af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown int ident = response.request.ident; 163af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown if (ident >= 0) { 16480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int fd = response.request.fd; 16580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int events = response.events; 16680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown void* data = response.request.data; 16759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 1689d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - returning signalled identifier %d: " 16980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown "fd=%d, events=0x%x, data=%p", 17080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, ident, fd, events, data); 17159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 17280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outFd != NULL) *outFd = fd; 17380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outEvents != NULL) *outEvents = events; 17480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (outData != NULL) *outData = data; 17580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown return ident; 17659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 17759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 17859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 17959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (result != 0) { 18059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 1819d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - returning result %d", this, result); 18259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 18359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (outFd != NULL) *outFd = 0; 184af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown if (outEvents != NULL) *outEvents = 0; 18559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (outData != NULL) *outData = NULL; 18659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 18759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 18859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 18959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = pollInner(timeoutMillis); 19059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 19159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 19259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 19359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollInner(int timeoutMillis) { 19459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 1959d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis); 19659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 19754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 19880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Adjust the timeout based on when the next message is due. 19980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) { 20080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 201c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime); 202c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown if (messageTimeoutMillis >= 0 203c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) { 204c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown timeoutMillis = messageTimeoutMillis; 20580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 20680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE 2079d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d", 20880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, mNextMessageUptime - now, timeoutMillis); 20980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 21080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 21180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 21280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Poll. 21354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int result = ALOOPER_POLL_WAKE; 21454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.clear(); 21554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponseIndex = 0; 21654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 21759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItems[EPOLL_MAX_EVENTS]; 21859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis); 21954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 22080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Acquire lock. 22180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 22280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 22380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll error. 22459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount < 0) { 225f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown if (errno == EINTR) { 22654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 22759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 22832397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Poll failed with an unexpected error, errno=%d", errno); 22954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_ERROR; 23054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 23159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 23259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 23380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Check for poll timeout. 23459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (eventCount == 0) { 23559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2369d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - timeout", this); 23759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 23854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown result = ALOOPER_POLL_TIMEOUT; 23954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown goto Done; 24059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 24159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 24280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Handle all events. 24359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 2449d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount); 24559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 24654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 247ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown for (int i = 0; i < eventCount; i++) { 248ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int fd = eventItems[i].data.fd; 249ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown uint32_t epollEvents = eventItems[i].events; 250ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (fd == mWakeReadPipeFd) { 251ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) { 25254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown awoken(); 25359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 25432397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents); 255ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } 256ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 257ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 258ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (requestIndex >= 0) { 259ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown int events = 0; 260ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT; 261ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT; 262ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR; 263ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP; 26454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown pushResponse(events, mRequests.valueAt(requestIndex)); 265ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown } else { 26632397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is " 267ed242de3f5b709e9e0925513ab976886a04358c0Jeff Brown "no longer registered.", epollEvents, fd); 26859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 26959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 27059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 27154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff BrownDone: ; 27254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 27380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke pending message callbacks. 27480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = LLONG_MAX; 27580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (mMessageEnvelopes.size() != 0) { 27680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 27780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0); 27880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.uptime <= now) { 27980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Remove the envelope from the list. 28080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // We keep a strong reference to the handler until the call to handleMessage 28180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // finishes. Then we drop it so that the handler can be deleted *before* 28280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // we reacquire our lock. 28380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // obtain handler 28480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sp<MessageHandler> handler = messageEnvelope.handler; 28580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown Message message = messageEnvelope.message; 28680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(0); 28780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = true; 28880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 28980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 29080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 2919d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d", 29280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, handler.get(), message.what); 29380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 29480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown handler->handleMessage(message); 29580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release handler 29680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 29780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.lock(); 29880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mSendingMessage = false; 29980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown result = ALOOPER_POLL_CALLBACK; 30080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } else { 30180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // The last message left at the head of the queue determines the next wakeup time. 30280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mNextMessageUptime = messageEnvelope.uptime; 30380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown break; 30480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 30580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 30680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 30780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Release lock. 30880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mLock.unlock(); 30980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 31080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Invoke all response callbacks. 31159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (size_t i = 0; i < mResponses.size(); i++) { 312af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown Response& response = mResponses.editItemAt(i); 313af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown if (response.request.ident == ALOOPER_POLL_CALLBACK) { 31480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int fd = response.request.fd; 31580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown int events = response.events; 31680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown void* data = response.request.data; 31759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS 3189d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p", 319af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown this, response.request.callback.get(), fd, events, data); 32059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 321af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown int callbackResult = response.request.callback->handleEvent(fd, events, data); 32259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (callbackResult == 0) { 32380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown removeFd(fd); 32459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 325af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown // Clear the callback reference in the response structure promptly because we 326af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown // will not clear the response vector itself until the next poll. 327af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown response.request.callback.clear(); 32859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = ALOOPER_POLL_CALLBACK; 32959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 33059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 33159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 33259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 33359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 33459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) { 33559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (timeoutMillis <= 0) { 33659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result; 33759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown do { 33859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown result = pollOnce(timeoutMillis, outFd, outEvents, outData); 33959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } while (result == ALOOPER_POLL_CALLBACK); 34059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 34159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 34259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC) 34359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown + milliseconds_to_nanoseconds(timeoutMillis); 34459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 34559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown for (;;) { 34659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int result = pollOnce(timeoutMillis, outFd, outEvents, outData); 34759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (result != ALOOPER_POLL_CALLBACK) { 34859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return result; 34959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 35059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 351c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 352c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown timeoutMillis = toMillisecondTimeoutDelay(now, endTime); 353c0a5e8df03d949cb307a0eb98f0222086c0434c1Jeff Brown if (timeoutMillis == 0) { 35459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return ALOOPER_POLL_TIMEOUT; 35559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 35659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 35759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 35859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 35959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 36059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownvoid Looper::wake() { 36159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_POLL_AND_WAKE 3629d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ wake", this); 36359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 36459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 365f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown ssize_t nWrite; 366f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown do { 367f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown nWrite = write(mWakeWritePipeFd, "W", 1); 368f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown } while (nWrite == -1 && errno == EINTR); 369f67f29903680e7a33af020dbeb80697ad619b26eJeff Brown 37059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (nWrite != 1) { 37159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (errno != EAGAIN) { 37232397c1cd3327905173b36baa6fd1c579bc328ffSteve Block ALOGW("Could not write wake signal, errno=%d", errno); 37359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 37459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 37559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 37659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 37754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::awoken() { 37854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#if DEBUG_POLL_AND_WAKE 3799d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ awoken", this); 38054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown#endif 38154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 38254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown char buffer[16]; 38354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown ssize_t nRead; 38454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown do { 38554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer)); 38654e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer)); 38754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 38854e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 38954e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brownvoid Looper::pushResponse(int events, const Request& request) { 39054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown Response response; 39154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.events = events; 39254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown response.request = request; 39354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown mResponses.push(response); 39454e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown} 39554e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 39659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) { 397af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data); 398af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown} 399af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown 400af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brownint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) { 40159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 4029d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident, 403af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown events, callback.get(), data); 40459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 40559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 406af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown if (!callback.get()) { 40759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (! mAllowNonCallbacks) { 408e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Invalid attempt to set NULL callback but not allowed for this looper."); 40959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 41059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 41159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 41259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (ident < 0) { 413af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown ALOGE("Invalid attempt to set NULL callback with ident < 0."); 41459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 41559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 416af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown } else { 417af567f73ac828b9c319c12fd92760c4c92f0dfa4Jeff Brown ident = ALOOPER_POLL_CALLBACK; 41859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 41959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 42054e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown int epollEvents = 0; 42154e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN; 42254e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT; 42354e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown 42459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 42559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 42659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 42759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown Request request; 42859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.fd = fd; 42959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.ident = ident; 43059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.callback = callback; 43159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown request.data = data; 43259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 43359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown struct epoll_event eventItem; 43461a25b249066baed0fdab0411f44a2c6b7292766Jeff Brown memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union 43559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.events = epollEvents; 43659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown eventItem.data.fd = fd; 43759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 43859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 43959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 44059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem); 44159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 442e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno); 44359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 44459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 44559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.add(fd, request); 44659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } else { 44759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem); 44859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 449e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno); 45059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 45159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.replaceValueAt(requestIndex, request); 45359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 45459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } // release lock 45559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 45659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 45759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 45859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brownint Looper::removeFd(int fd) { 45959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#if DEBUG_CALLBACKS 4609d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeFd - fd=%d", this, fd); 46159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown#endif 46259abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 46359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown { // acquire lock 46459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown AutoMutex _l(mLock); 46559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown ssize_t requestIndex = mRequests.indexOfKey(fd); 46659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (requestIndex < 0) { 46759abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 0; 46859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 46959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 47059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL); 47159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown if (epollResult < 0) { 472e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno); 47359abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return -1; 47459abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown } 47559abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 47659abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown mRequests.removeItemsAt(requestIndex); 47754e1cdacd2b132997fdca5e5b90e45855c7a2a95Jeff Brown } // release lock 47859abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown return 1; 47959abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} 48059abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown 48180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) { 4824815f2a6ada7941680b29581d5cf5a5ed168f618Jeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 4834815f2a6ada7941680b29581d5cf5a5ed168f618Jeff Brown sendMessageAtTime(now, handler, message); 48480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 48580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 48680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler, 48780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 48880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); 48980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown sendMessageAtTime(now + uptimeDelay, handler, message); 49080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 49180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 49280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler, 49380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const Message& message) { 49480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 4959d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d", 49680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown this, uptime, handler.get(), message.what); 49780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 49880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 49980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t i = 0; 50080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 50180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 50280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 50380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown size_t messageCount = mMessageEnvelopes.size(); 50480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) { 50580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown i += 1; 50680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 50780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 50880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown MessageEnvelope messageEnvelope(uptime, handler, message); 50980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.insertAt(messageEnvelope, i, 1); 51080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 51180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Optimization: If the Looper is currently sending a message, then we can skip 51280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // the call to wake() because the next thing the Looper will do after processing 51380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // messages is to decide when the next wakeup time should be. In fact, it does 51480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // not even matter whether this code is running on the Looper thread. 51580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (mSendingMessage) { 51680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown return; 51780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 51880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 51980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 52080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown // Wake the poll loop only when we enqueue a new message at the head. 52180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (i == 0) { 52280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown wake(); 52380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 52480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 52580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 52680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) { 52780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 5289d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeMessages - handler=%p", this, handler.get()); 52980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 53080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 53180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 53280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 53380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 53480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 53580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 53680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler) { 53780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 53880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 53980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 54080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 54180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 54280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 54380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) { 54480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#if DEBUG_CALLBACKS 5459d4536835248525f32f1504a3d28d5bbfa0a2910Steve Block ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what); 54680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown#endif 54780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 54880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown { // acquire lock 54980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown AutoMutex _l(mLock); 55080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 55180f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown for (size_t i = mMessageEnvelopes.size(); i != 0; ) { 55280f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i); 55380f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown if (messageEnvelope.handler == handler 55480f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown && messageEnvelope.message.what == what) { 55580f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown mMessageEnvelopes.removeAt(i); 55680f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 55780f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } 55880f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown } // release lock 55980f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown} 56080f3e7cc1506bbb4bec458e15629805a7c1df7eeJeff Brown 56159abe7e0909bf4b7bf7b9601e1e40a05f6d4fd8aJeff Brown} // namespace android 562