Looper.cpp revision 6ed68cc412752e4c78755df9a1516e610ec66fa8
17901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
27901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Copyright 2010 The Android Open Source Project
37901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
47901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// A looper implementation based on epoll().
57901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//
67901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define LOG_TAG "Looper"
77901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
87901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown//#define LOG_NDEBUG 0
97901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs poll and wake interactions.
117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_POLL_AND_WAKE 0
127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Debugs callback registration and invocation.
147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#define DEBUG_CALLBACKS 0
157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <cutils/log.h>
177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Looper.h>
187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <utils/Timers.h>
197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
206ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <errno.h>
217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#include <fcntl.h>
223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#include <limits.h>
236ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <string.h>
246ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes#include <unistd.h>
257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android {
287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler ---
303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mHandler(handler) {
333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
35dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownWeakMessageHandler::~WeakMessageHandler() {
36dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
37dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) {
393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sp<MessageHandler> handler = mHandler.promote();
403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (handler != NULL) {
413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        handler->handleMessage(message);
423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
46dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown// --- SimpleLooperCallback ---
47dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
481693d7e48f976c2615100378c7e98d245e0213beBrian CarlstromSimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :
49dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown        mCallback(callback) {
50dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
51dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
52dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownSimpleLooperCallback::~SimpleLooperCallback() {
53dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
54dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
55dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
56dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    return mCallback(fd, events, data);
57dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
58dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
59dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper ---
613e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance.
637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8;
647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration.
667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16;
677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
68d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
69d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0;
70d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) :
723e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int wakeFds[2];
757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int result = pipe(wakeFds);
766ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe: %s", strerror(errno));
777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    mWakeReadPipeFd = wakeFds[0];
797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    mWakeWritePipeFd = wakeFds[1];
807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking: %s",
836ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes            strerror(errno));
847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
866ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking: %s",
876ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes            strerror(errno));
887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
8919159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    mIdling = false;
9019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    // Allocate the epoll instance and register the wake pipe.
928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
936ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct epoll_event eventItem;
96d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    eventItem.events = EPOLLIN;
987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    eventItem.data.fd = mWakeReadPipeFd;
997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
1006ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance: %s",
1016ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes            strerror(errno));
1027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() {
1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mWakeReadPipeFd);
1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mWakeWritePipeFd);
1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    close(mEpollFd);
1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
110d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() {
111d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_key_create(& gTLSKey, threadDestructor);
112d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
113d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown}
114d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) {
1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Looper* const self = static_cast<Looper*>(st);
1177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (self != NULL) {
1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        self->decStrong((void*)threadDestructor);
1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) {
1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
1247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper != NULL) {
1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper->incStrong((void*)threadDestructor);
1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
129d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    pthread_setspecific(gTLSKey, looper.get());
1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (old != NULL) {
1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        old->decStrong((void*)threadDestructor);
1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() {
137d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_once(& gTLSOnce, initTLSKey);
138d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
1397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
140d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    return (Looper*)pthread_getspecific(gTLSKey);
1417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) {
1441693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
1457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> looper = Looper::getForThread();
1467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper == NULL) {
1477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper = new Looper(allowNonCallbacks);
1487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Looper::setForThread(looper);
1497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
15161d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block        ALOGW("Looper already prepared for this thread with a different value for the "
1521693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
1537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return looper;
1557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const {
1587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return mAllowNonCallbacks;
1597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
1627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int result = 0;
1637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (;;) {
1647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        while (mResponseIndex < mResponses.size()) {
1657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            const Response& response = mResponses.itemAt(mResponseIndex++);
166dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            int ident = response.request.ident;
167dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            if (ident >= 0) {
1683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int fd = response.request.fd;
1693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int events = response.events;
1703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                void* data = response.request.data;
1717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
172eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
1733e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        "fd=%d, events=0x%x, data=%p",
1743e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, ident, fd, events, data);
1757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
1763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outFd != NULL) *outFd = fd;
1773e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outEvents != NULL) *outEvents = events;
1783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outData != NULL) *outData = data;
1793e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                return ident;
1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (result != 0) {
1847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
185eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block            ALOGD("%p ~ pollOnce - returning result %d", this, result);
1867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
1877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outFd != NULL) *outFd = 0;
188dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            if (outEvents != NULL) *outEvents = 0;
1897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outData != NULL) *outData = NULL;
1907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return result;
1917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        result = pollInner(timeoutMillis);
1947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) {
1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
199eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Adjust the timeout based on when the next message is due.
2033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
2043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
20543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
20643550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        if (messageTimeoutMillis >= 0
20743550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
20843550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = messageTimeoutMillis;
2093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
2103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE
211eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        ALOGD("%p ~ pollOnce - next message in %lldns, adjusted timeout: timeoutMillis=%d",
2123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                this, mNextMessageUptime - now, timeoutMillis);
2133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
2143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
2153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
2163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Poll.
2171693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    int result = POLL_WAKE;
2188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.clear();
2198d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponseIndex = 0;
2208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
22119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    // We are about to idle.
22219159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    mIdling = true;
22319159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
2247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
2257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
2268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
22719159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    // No longer idling.
22819159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    mIdling = false;
22919159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Acquire lock.
2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.lock();
2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
2333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll error.
2347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount < 0) {
235171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        if (errno == EINTR) {
2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            goto Done;
2377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
2386ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes        ALOGW("Poll failed with an unexpected error: %s", strerror(errno));
2391693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        result = POLL_ERROR;
2408d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll timeout.
2447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount == 0) {
2457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
246eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        ALOGD("%p ~ pollOnce - timeout", this);
2477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2481693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        result = POLL_TIMEOUT;
2498d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Handle all events.
2537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
254eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
2557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2568d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2579da1810050d8825e51dabdd0262173432d49c16cJeff Brown    for (int i = 0; i < eventCount; i++) {
2589da1810050d8825e51dabdd0262173432d49c16cJeff Brown        int fd = eventItems[i].data.fd;
2599da1810050d8825e51dabdd0262173432d49c16cJeff Brown        uint32_t epollEvents = eventItems[i].events;
2609da1810050d8825e51dabdd0262173432d49c16cJeff Brown        if (fd == mWakeReadPipeFd) {
2619da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (epollEvents & EPOLLIN) {
2628d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                awoken();
2637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            } else {
26461d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block                ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
2659da1810050d8825e51dabdd0262173432d49c16cJeff Brown            }
2669da1810050d8825e51dabdd0262173432d49c16cJeff Brown        } else {
2679da1810050d8825e51dabdd0262173432d49c16cJeff Brown            ssize_t requestIndex = mRequests.indexOfKey(fd);
2689da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (requestIndex >= 0) {
2699da1810050d8825e51dabdd0262173432d49c16cJeff Brown                int events = 0;
2701693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
2711693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
2721693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
2731693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
2748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                pushResponse(events, mRequests.valueAt(requestIndex));
2759da1810050d8825e51dabdd0262173432d49c16cJeff Brown            } else {
27661d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block                ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
2779da1810050d8825e51dabdd0262173432d49c16cJeff Brown                        "no longer registered.", epollEvents, fd);
2787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
2797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
2807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2818d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ;
2828d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke pending message callbacks.
2843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mNextMessageUptime = LLONG_MAX;
2853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    while (mMessageEnvelopes.size() != 0) {
2863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
2873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
2883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (messageEnvelope.uptime <= now) {
2893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // Remove the envelope from the list.
2903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // We keep a strong reference to the handler until the call to handleMessage
2913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // finishes.  Then we drop it so that the handler can be deleted *before*
2923e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // we reacquire our lock.
2933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            { // obtain handler
2943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                sp<MessageHandler> handler = messageEnvelope.handler;
2953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                Message message = messageEnvelope.message;
2963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(0);
2973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mSendingMessage = true;
2983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mLock.unlock();
2993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
301eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
3023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, handler.get(), message.what);
3033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
3043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                handler->handleMessage(message);
3053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            } // release handler
3063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mLock.lock();
3083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mSendingMessage = false;
3091693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            result = POLL_CALLBACK;
3103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        } else {
3113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // The last message left at the head of the queue determines the next wakeup time.
3123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mNextMessageUptime = messageEnvelope.uptime;
3133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            break;
3143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
3153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
3163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Release lock.
3183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.unlock();
3193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke all response callbacks.
3217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (size_t i = 0; i < mResponses.size(); i++) {
322dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown        Response& response = mResponses.editItemAt(i);
3231693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        if (response.request.ident == POLL_CALLBACK) {
3243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int fd = response.request.fd;
3253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int events = response.events;
3263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            void* data = response.request.data;
3277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
328eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block            ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
329dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown                    this, response.request.callback.get(), fd, events, data);
3307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
331dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            int callbackResult = response.request.callback->handleEvent(fd, events, data);
3327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (callbackResult == 0) {
3333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                removeFd(fd);
3347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
335dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            // Clear the callback reference in the response structure promptly because we
336dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            // will not clear the response vector itself until the next poll.
337dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            response.request.callback.clear();
3381693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            result = POLL_CALLBACK;
3397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return result;
3427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
3437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
3457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (timeoutMillis <= 0) {
3467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int result;
3477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        do {
3487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            result = pollOnce(timeoutMillis, outFd, outEvents, outData);
3491693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        } while (result == POLL_CALLBACK);
3507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        return result;
3517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } else {
3527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
3537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                + milliseconds_to_nanoseconds(timeoutMillis);
3547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        for (;;) {
3567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
3571693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            if (result != POLL_CALLBACK) {
3587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return result;
3597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
36143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
36243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
36343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            if (timeoutMillis == 0) {
3641693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                return POLL_TIMEOUT;
3657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
3697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() {
3717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
372eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ wake", this);
3737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
3747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
375171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    ssize_t nWrite;
376171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    do {
377171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        nWrite = write(mWakeWritePipeFd, "W", 1);
378171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown    } while (nWrite == -1 && errno == EINTR);
379171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown
3807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (nWrite != 1) {
3817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (errno != EAGAIN) {
3826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes            ALOGW("Could not write wake signal: %s", strerror(errno));
3837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
3867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() {
3888d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE
389eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ awoken", this);
3908d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
3918d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
3928d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    char buffer[16];
3938d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    ssize_t nRead;
3948d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    do {
3958d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
3968d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
3978d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
3988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
3998d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) {
4008d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    Response response;
4018d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.events = events;
4028d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.request = request;
4038d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.push(response);
4048d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
4058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4061693d7e48f976c2615100378c7e98d245e0213beBrian Carlstromint Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
407dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
408dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
409dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
410dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
4117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
412eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
413dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            events, callback.get(), data);
4147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
416dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    if (!callback.get()) {
4177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (! mAllowNonCallbacks) {
4181b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
4197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
4207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (ident < 0) {
423dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            ALOGE("Invalid attempt to set NULL callback with ident < 0.");
4247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
4257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
426dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    } else {
4271693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        ident = POLL_CALLBACK;
4287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4308d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    int epollEvents = 0;
4311693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    if (events & EVENT_INPUT) epollEvents |= EPOLLIN;
4321693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT;
4338d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
4357901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
4367901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Request request;
4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.fd = fd;
4397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.ident = ident;
4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.callback = callback;
4417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.data = data;
4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        struct epoll_event eventItem;
444d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown        memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
4457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        eventItem.events = epollEvents;
4467901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        eventItem.data.fd = fd;
4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
4497901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
4507901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
4526ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes                ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));
4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return -1;
4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.add(fd, request);
4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        } else {
4577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
4587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
4596ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes                ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));
4607901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return -1;
4617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.replaceValueAt(requestIndex, request);
4637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } // release lock
4657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
4667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) {
4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
470eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ removeFd - fd=%d", this, fd);
4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
4767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
4777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return 0;
4787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
4817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (epollResult < 0) {
4826ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes            ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno));
4837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
4847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4857901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        mRequests.removeItemsAt(requestIndex);
4878d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } // release lock
4887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
4897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
492aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
493aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown    sendMessageAtTime(now, handler, message);
4943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
4953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
4963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
4973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
4983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
4993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sendMessageAtTime(now + uptimeDelay, handler, message);
5003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
5033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
5043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
505eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ sendMessageAtTime - uptime=%lld, handler=%p, what=%d",
5063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            this, uptime, handler.get(), message.what);
5073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
5083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    size_t i = 0;
5103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
5113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
5123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        size_t messageCount = mMessageEnvelopes.size();
5143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
5153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            i += 1;
5163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
5173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        MessageEnvelope messageEnvelope(uptime, handler, message);
5193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
5203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // Optimization: If the Looper is currently sending a message, then we can skip
5223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // the call to wake() because the next thing the Looper will do after processing
5233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // messages is to decide when the next wakeup time should be.  In fact, it does
5243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // not even matter whether this code is running on the Looper thread.
5253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (mSendingMessage) {
5263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            return;
5273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
5283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
5293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Wake the poll loop only when we enqueue a new message at the head.
5313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (i == 0) {
5323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        wake();
5333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
5343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) {
5373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
538eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ removeMessages - handler=%p", this, handler.get());
5393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
5403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
5423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
5433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
5453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
5463e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler) {
5473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
5483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
5493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
5503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
5513e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
5543e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
555eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
5563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
5573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5583e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
5593e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
5603e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5613e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
5623e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
5633e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler
5643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                    && messageEnvelope.message.what == what) {
5653e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
5663e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
5673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
5683e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
5693e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5703e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
57119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackbornbool Looper::isIdling() const {
57219159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    return mIdling;
57319159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn}
57419159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
5757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android
576