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