Looper.cpp revision 43550eee5bfeaf7832487a2285ae86be0f7ce561
17901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
27901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Copyright 2010 The Android Open Source Project
37901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
47901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// A looper implementation based on epoll().
57901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
67901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define LOG_TAG "Looper"
77901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
87901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//#define LOG_NDEBUG 0
97901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs poll and wake interactions.
117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_POLL_AND_WAKE 0
127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs callback registration and invocation.
147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_CALLBACKS 0
157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <cutils/log.h>
177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Looper.h>
187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Timers.h>
197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <unistd.h>
217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <fcntl.h>
223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#include <limits.h>
237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android {
267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler ---
283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mHandler(handler) {
313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) {
343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sp<MessageHandler> handler = mHandler.promote();
353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (handler != NULL) {
363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        handler->handleMessage(message);
373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper ---
423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance.
457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8;
467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration.
487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16;
498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
51d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
52d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0;
53d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) :
553e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int wakeFds[2];
587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int result = pipe(wakeFds);
597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    mWakeReadPipeFd = wakeFds[0];
627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    mWakeWritePipeFd = wakeFds[1];
637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            errno);
677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            errno);
717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
728d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // Allocate the epoll instance and register the wake pipe.
748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct epoll_event eventItem;
78d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    eventItem.events = EPOLLIN;
807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    eventItem.data.fd = mWakeReadPipeFd;
817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            errno);
848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else
858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // Add the wake pipe to the head of the request list with a null callback.
868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    struct pollfd requestedFd;
878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    requestedFd.fd = mWakeReadPipeFd;
888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    requestedFd.events = POLLIN;
898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mRequestedFds.push(requestedFd);
908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    Request request;
928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.fd = mWakeReadPipeFd;
938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.callback = NULL;
948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.ident = 0;
958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.data = NULL;
968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mRequests.push(request);
978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mPolling = false;
998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mWaiters = 0;
1008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
1018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
1028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS
1038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mPendingWakeTime = -1;
1048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mPendingWakeCount = 0;
1058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledWakeCycles = 0;
1068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledWakeCountSum = 0;
1078d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledWakeLatencySum = 0;
1088d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
1098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledPolls = 0;
1108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledZeroPollCount = 0;
1118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledZeroPollLatencySum = 0;
1128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledTimeoutPollCount = 0;
1138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledTimeoutPollLatencySum = 0;
1148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() {
1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mWakeReadPipeFd);
1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mWakeWritePipeFd);
1208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mEpollFd);
1228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
125d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() {
126d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_key_create(& gTLSKey, threadDestructor);
127d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
128d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown}
129d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) {
1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Looper* const self = static_cast<Looper*>(st);
1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (self != NULL) {
1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        self->decStrong((void*)threadDestructor);
1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) {
1387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper != NULL) {
1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper->incStrong((void*)threadDestructor);
1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
144d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    pthread_setspecific(gTLSKey, looper.get());
1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (old != NULL) {
1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        old->decStrong((void*)threadDestructor);
1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() {
152d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_once(& gTLSOnce, initTLSKey);
153d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
155d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    return (Looper*)pthread_getspecific(gTLSKey);
1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) {
1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS;
1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> looper = Looper::getForThread();
1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper == NULL) {
1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper = new Looper(allowNonCallbacks);
1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Looper::setForThread(looper);
1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
1667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        LOGW("Looper already prepared for this thread with a different value for the "
1677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
1687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return looper;
1707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const {
1737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return mAllowNonCallbacks;
1747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
1777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int result = 0;
1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (;;) {
1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        while (mResponseIndex < mResponses.size()) {
1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            const Response& response = mResponses.itemAt(mResponseIndex++);
1813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            ALooper_callbackFunc callback = response.request.callback;
1823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (!callback) {
1833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int ident = response.request.ident;
1843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int fd = response.request.fd;
1853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int events = response.events;
1863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                void* data = response.request.data;
1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                LOGD("%p ~ pollOnce - returning signalled identifier %d: "
1893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        "fd=%d, events=0x%x, data=%p",
1903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, ident, fd, events, data);
1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
1923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outFd != NULL) *outFd = fd;
1933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outEvents != NULL) *outEvents = events;
1943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outData != NULL) *outData = data;
1953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                return ident;
1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (result != 0) {
2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            LOGD("%p ~ pollOnce - returning result %d", this, result);
2027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outFd != NULL) *outFd = 0;
2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outEvents != NULL) *outEvents = NULL;
2057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outData != NULL) *outData = NULL;
2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return result;
2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        result = pollInner(timeoutMillis);
2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) {
2147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
2157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
2167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Adjust the timeout based on when the next message is due.
2193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
2203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
22143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
22243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        if (messageTimeoutMillis >= 0
22343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
22443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = messageTimeoutMillis;
2253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
2263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE
2273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        LOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
2283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                this, mNextMessageUptime - now, timeoutMillis);
2293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Poll.
2338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    int result = ALOOPER_POLL_WAKE;
2348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.clear();
2358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponseIndex = 0;
2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS
2388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
2398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
2408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
2437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
2448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else
2458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // Wait for wakeAndLock() waiters to run then set mPolling to true.
2468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mLock.lock();
2478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    while (mWaiters != 0) {
2488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mResume.wait(mLock);
2498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
2508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mPolling = true;
2518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mLock.unlock();
2528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    size_t requestedCount = mRequestedFds.size();
2548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
2558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
2568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Acquire lock.
2583e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.lock();
2593e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
2603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll error.
2617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount < 0) {
262171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        if (errno == EINTR) {
2638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            goto Done;
2647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
265171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        LOGW("Poll failed with an unexpected error, errno=%d", errno);
2668d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        result = ALOOPER_POLL_ERROR;
2678d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll timeout.
2717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount == 0) {
2727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
2737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        LOGD("%p ~ pollOnce - timeout", this);
2747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        result = ALOOPER_POLL_TIMEOUT;
2768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Handle all events.
2807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
2817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
2827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
2859da1810050d8825e51dabdd0262173432d49c16cJeff Brown    for (int i = 0; i < eventCount; i++) {
2869da1810050d8825e51dabdd0262173432d49c16cJeff Brown        int fd = eventItems[i].data.fd;
2879da1810050d8825e51dabdd0262173432d49c16cJeff Brown        uint32_t epollEvents = eventItems[i].events;
2889da1810050d8825e51dabdd0262173432d49c16cJeff Brown        if (fd == mWakeReadPipeFd) {
2899da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (epollEvents & EPOLLIN) {
2908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                awoken();
2917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            } else {
2929da1810050d8825e51dabdd0262173432d49c16cJeff Brown                LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
2939da1810050d8825e51dabdd0262173432d49c16cJeff Brown            }
2949da1810050d8825e51dabdd0262173432d49c16cJeff Brown        } else {
2959da1810050d8825e51dabdd0262173432d49c16cJeff Brown            ssize_t requestIndex = mRequests.indexOfKey(fd);
2969da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (requestIndex >= 0) {
2979da1810050d8825e51dabdd0262173432d49c16cJeff Brown                int events = 0;
2989da1810050d8825e51dabdd0262173432d49c16cJeff Brown                if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
2999da1810050d8825e51dabdd0262173432d49c16cJeff Brown                if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
3009da1810050d8825e51dabdd0262173432d49c16cJeff Brown                if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
3019da1810050d8825e51dabdd0262173432d49c16cJeff Brown                if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
3028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                pushResponse(events, mRequests.valueAt(requestIndex));
3039da1810050d8825e51dabdd0262173432d49c16cJeff Brown            } else {
3049da1810050d8825e51dabdd0262173432d49c16cJeff Brown                LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
3059da1810050d8825e51dabdd0262173432d49c16cJeff Brown                        "no longer registered.", epollEvents, fd);
3067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ;
3108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else
3118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    for (size_t i = 0; i < requestedCount; i++) {
3128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        const struct pollfd& requestedFd = mRequestedFds.itemAt(i);
3138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
3148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        short pollEvents = requestedFd.revents;
3158d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        if (pollEvents) {
3168d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            if (requestedFd.fd == mWakeReadPipeFd) {
3178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLIN) {
3188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                    awoken();
3198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                } else {
3208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                    LOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents);
3218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                }
3228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            } else {
3238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                int events = 0;
3248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT;
3258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT;
3268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR;
3278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP;
3288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID;
3298d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                pushResponse(events, mRequests.itemAt(i));
3308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            }
3318d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            if (--eventCount == 0) {
3328d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                break;
3338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            }
3348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        }
3358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
3368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone:
3378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // Set mPolling to false and wake up the wakeAndLock() waiters.
3388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mPolling = false;
3398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (mWaiters != 0) {
3408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mAwake.broadcast();
3418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
3428d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
3438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
3448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS
3458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
3468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mSampledPolls += 1;
3478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (timeoutMillis == 0) {
3488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledZeroPollCount += 1;
3498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledZeroPollLatencySum += pollEndTime - pollStartTime;
3508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) {
3518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledTimeoutPollCount += 1;
3528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime
3538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                - milliseconds_to_nanoseconds(timeoutMillis);
3548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
3558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) {
3568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        LOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this,
3578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount,
3588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount);
3598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledPolls = 0;
3608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledZeroPollCount = 0;
3618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledZeroPollLatencySum = 0;
3628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledTimeoutPollCount = 0;
3638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledTimeoutPollLatencySum = 0;
3648d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
3658d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
3667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke pending message callbacks.
3683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mNextMessageUptime = LLONG_MAX;
3693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    while (mMessageEnvelopes.size() != 0) {
3703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
3713e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
3723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (messageEnvelope.uptime <= now) {
3733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // Remove the envelope from the list.
3743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // We keep a strong reference to the handler until the call to handleMessage
3753e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // finishes.  Then we drop it so that the handler can be deleted *before*
3763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // we reacquire our lock.
3773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            { // obtain handler
3783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                sp<MessageHandler> handler = messageEnvelope.handler;
3793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                Message message = messageEnvelope.message;
3803e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(0);
3813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mSendingMessage = true;
3823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mLock.unlock();
3833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
3853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                LOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
3863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, handler.get(), message.what);
3873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
3883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                handler->handleMessage(message);
3893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            } // release handler
3903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mLock.lock();
3923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mSendingMessage = false;
3933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            result = ALOOPER_POLL_CALLBACK;
3943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        } else {
3953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // The last message left at the head of the queue determines the next wakeup time.
3963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mNextMessageUptime = messageEnvelope.uptime;
3973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            break;
3983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
3993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
4003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
4013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Release lock.
4023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.unlock();
4033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
4043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke all response callbacks.
4057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (size_t i = 0; i < mResponses.size(); i++) {
4067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        const Response& response = mResponses.itemAt(i);
4073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        ALooper_callbackFunc callback = response.request.callback;
4083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (callback) {
4093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int fd = response.request.fd;
4103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int events = response.events;
4113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            void* data = response.request.data;
4127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
4133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            LOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
4143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                    this, callback, fd, events, data);
4157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int callbackResult = callback(fd, events, data);
4177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (callbackResult == 0) {
4183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                removeFd(fd);
4197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            result = ALOOPER_POLL_CALLBACK;
4217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return result;
4247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
4277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (timeoutMillis <= 0) {
4287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int result;
4297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        do {
4307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            result = pollOnce(timeoutMillis, outFd, outEvents, outData);
4317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        } while (result == ALOOPER_POLL_CALLBACK);
4327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        return result;
4337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } else {
4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
4357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                + milliseconds_to_nanoseconds(timeoutMillis);
4367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        for (;;) {
4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
4397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (result != ALOOPER_POLL_CALLBACK) {
4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return result;
4417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
44343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
44443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
44543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            if (timeoutMillis == 0) {
4467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return ALOOPER_POLL_TIMEOUT;
4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() {
4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOGD("%p ~ wake", this);
4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS
4588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled.
4598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (mPendingWakeCount++ == 0) {
4608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC);
4618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
4628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
4638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
464171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    ssize_t nWrite;
465171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    do {
466171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        nWrite = write(mWakeWritePipeFd, "W", 1);
467171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    } while (nWrite == -1 && errno == EINTR);
468171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown
4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (nWrite != 1) {
4707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (errno != EAGAIN) {
4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            LOGW("Could not write wake signal, errno=%d", errno);
4727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() {
4778d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE
4788d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    LOGD("%p ~ awoken", this);
4798d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
4808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_STATISTICS
4828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (mPendingWakeCount == 0) {
4838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        LOGD("%p ~ awoken: spurious!", this);
4848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } else {
4858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledWakeCycles += 1;
4868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledWakeCountSum += mPendingWakeCount;
4878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime;
4888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mPendingWakeCount = 0;
4898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mPendingWakeTime = -1;
4908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) {
4918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            LOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this,
4928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                    0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles,
4938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                    float(mSampledWakeCountSum) / mSampledWakeCycles);
4948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            mSampledWakeCycles = 0;
4958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            mSampledWakeCountSum = 0;
4968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            mSampledWakeLatencySum = 0;
4978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        }
4988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
4998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
5008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    char buffer[16];
5028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    ssize_t nRead;
5038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    do {
5048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
5058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
5068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
5078d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5088d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) {
5098d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    Response response;
5108d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.events = events;
5118d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.request = request;
5128d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.push(response);
5138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
5148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) {
5167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
5177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
5187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            events, callback, data);
5197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
5207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (! callback) {
5227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (! mAllowNonCallbacks) {
5237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            LOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
5247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
5257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (ident < 0) {
5287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            LOGE("Invalid attempt to set NULL callback with ident <= 0.");
5297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
5307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
5327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
5348d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    int epollEvents = 0;
5358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN;
5368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT;
5378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
5397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
5407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Request request;
5427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.fd = fd;
5437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.ident = ident;
5447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.callback = callback;
5457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.data = data;
5467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        struct epoll_event eventItem;
548d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown        memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
5497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        eventItem.events = epollEvents;
5507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        eventItem.data.fd = fd;
5517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
5537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
5547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
5557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
5567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                LOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);
5577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return -1;
5587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
5597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.add(fd, request);
5607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        } else {
5617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
5627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
5637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                LOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno);
5647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return -1;
5657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
5667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.replaceValueAt(requestIndex, request);
5677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } // release lock
5698d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else
5708d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    int pollEvents = 0;
5718d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN;
5728d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT;
5738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    wakeAndLock(); // acquire lock
5758d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5768d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    struct pollfd requestedFd;
5778d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    requestedFd.fd = fd;
5788d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    requestedFd.events = pollEvents;
5798d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    Request request;
5818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.fd = fd;
5828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.ident = ident;
5838d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.callback = callback;
5848d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    request.data = data;
5858d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    ssize_t index = getRequestIndexLocked(fd);
5868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (index < 0) {
5878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequestedFds.push(requestedFd);
5888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequests.push(request);
5898d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } else {
5908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequestedFds.replaceAt(requestedFd, size_t(index));
5918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequests.replaceAt(request, size_t(index));
5928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
5938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
5948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mLock.unlock(); // release lock
5958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
5967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
5977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
5987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) {
6007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
6017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    LOGD("%p ~ removeFd - fd=%d", this, fd);
6027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
6037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
6048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifdef LOOPER_USES_EPOLL
6057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
6067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
6077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
6087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
6097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return 0;
6107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
6117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
6127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
6137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (epollResult < 0) {
6147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            LOGE("Error removing epoll events for fd %d, errno=%d", fd, errno);
6157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
6167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
6177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
6187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        mRequests.removeItemsAt(requestIndex);
6198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } // release lock
6207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
6218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#else
6228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    wakeAndLock(); // acquire lock
6238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    ssize_t index = getRequestIndexLocked(fd);
6258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (index >= 0) {
6268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequestedFds.removeAt(size_t(index));
6278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mRequests.removeAt(size_t(index));
6288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
6298d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mLock.unlock(); // release lock
6318d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    return index >= 0;
6328d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
6337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
6347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
6358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#ifndef LOOPER_USES_EPOLL
6368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownssize_t Looper::getRequestIndexLocked(int fd) {
6378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    size_t requestCount = mRequestedFds.size();
6388d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6398d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    for (size_t i = 0; i < requestCount; i++) {
6408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        if (mRequestedFds.itemAt(i).fd == fd) {
6418d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            return i;
6428d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        }
6438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
6448d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6458d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    return -1;
6468d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
6478d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6488d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::wakeAndLock() {
6498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mLock.lock();
6508d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6518d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mWaiters += 1;
6528d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    while (mPolling) {
6538d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        wake();
6548d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mAwake.wait(mLock);
6558d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
6568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6578d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mWaiters -= 1;
6588d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    if (mWaiters == 0) {
6598d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        mResume.signal();
6608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    }
6618d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
6628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
6638d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
6643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
6653e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sendMessageAtTime(LLONG_MIN, handler, message);
6663e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
6673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
6693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
6703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
6713e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sendMessageAtTime(now + uptimeDelay, handler, message);
6723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
6733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
6753e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
6763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
6773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    LOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",
6783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            this, uptime, handler.get(), message.what);
6793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
6803e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    size_t i = 0;
6823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
6833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
6843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        size_t messageCount = mMessageEnvelopes.size();
6863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
6873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            i += 1;
6883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
6893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        MessageEnvelope messageEnvelope(uptime, handler, message);
6913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
6923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // Optimization: If the Looper is currently sending a message, then we can skip
6943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // the call to wake() because the next thing the Looper will do after processing
6953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // messages is to decide when the next wakeup time should be.  In fact, it does
6963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // not even matter whether this code is running on the Looper thread.
6973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (mSendingMessage) {
6983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            return;
6993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
7003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
7013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Wake the poll loop only when we enqueue a new message at the head.
7033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (i == 0) {
7043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        wake();
7053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
7063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
7073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) {
7093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
7103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    LOGD("%p ~ removeMessages - handler=%p", this, handler.get());
7113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
7123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
7143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
7153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
7173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
7183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler) {
7193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
7203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
7213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
7223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
7233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
7243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
7263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
7273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    LOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
7283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
7293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
7313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
7323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
7343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
7353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler
7363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                    && messageEnvelope.message.what == what) {
7373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
7383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
7393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
7403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
7413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
7423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
7437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android
744