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