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