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
1666ce3e08c5632a20ea66bde6dd76397041edf034Mark Salyzyn#include <utils/Looper.h>
1722dbf3947fedf988e714a4703ddf85fc41413f90Mathias Agopian#include <sys/eventfd.h>
187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownnamespace android {
207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- WeakMessageHandler ---
223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff BrownWeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mHandler(handler) {
253e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
27dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownWeakMessageHandler::~WeakMessageHandler() {
28dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
29dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid WeakMessageHandler::handleMessage(const Message& message) {
313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sp<MessageHandler> handler = mHandler.promote();
323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (handler != NULL) {
333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        handler->handleMessage(message);
343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
38dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown// --- SimpleLooperCallback ---
39dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
401693d7e48f976c2615100378c7e98d245e0213beBrian CarlstromSimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :
41dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown        mCallback(callback) {
42dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
43dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
44dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff BrownSimpleLooperCallback::~SimpleLooperCallback() {
45dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
46dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
47dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
48dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    return mCallback(fd, events, data);
49dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
50dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
51dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown// --- Looper ---
533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Hint for number of file descriptors to be associated with the epoll instance.
557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_SIZE_HINT = 8;
567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown// Maximum number of file descriptors for which to retrieve poll events each iteration.
587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownstatic const int EPOLL_MAX_EVENTS = 16;
597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
60d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
61d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownstatic pthread_key_t gTLSKey = 0;
62d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
637901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::Looper(bool allowNonCallbacks) :
643e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
65e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
667a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
67c68c8862f954fdd7c6cc6ebc331bba969bd06919Nick Kralevich    mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
685b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes    LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
695b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                        strerror(errno));
707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
71e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    AutoMutex _l(mLock);
72e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    rebuildEpollLocked();
737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff BrownLooper::~Looper() {
768892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    close(mWakeEventFd);
7748c35dbe5044ef07afda15ccc105a7018006eca6John Reck    mWakeEventFd = -1;
78e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (mEpollFd >= 0) {
79e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        close(mEpollFd);
80e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    }
817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
83d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brownvoid Looper::initTLSKey() {
84d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_key_create(& gTLSKey, threadDestructor);
85d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
86d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown}
87d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown
887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::threadDestructor(void *st) {
897901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    Looper* const self = static_cast<Looper*>(st);
907901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (self != NULL) {
917901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        self->decStrong((void*)threadDestructor);
927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::setForThread(const sp<Looper>& looper) {
967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper != NULL) {
997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper->incStrong((void*)threadDestructor);
1007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
102d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    pthread_setspecific(gTLSKey, looper.get());
1037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (old != NULL) {
1057901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        old->decStrong((void*)threadDestructor);
1067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::getForThread() {
110d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    int result = pthread_once(& gTLSOnce, initTLSKey);
111d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
1127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
113d18051870e8e2a5f55237a2c11fde75f46082639Jeff Brown    return (Looper*)pthread_getspecific(gTLSKey);
1147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownsp<Looper> Looper::prepare(int opts) {
1171693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
1187901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    sp<Looper> looper = Looper::getForThread();
1197901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper == NULL) {
1207901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        looper = new Looper(allowNonCallbacks);
1217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Looper::setForThread(looper);
1227901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
12461d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block        ALOGW("Looper already prepared for this thread with a different value for the "
1251693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
1267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
1277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return looper;
1287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
1307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownbool Looper::getAllowNonCallbacks() const {
1317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return mAllowNonCallbacks;
1327901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
1337901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
134e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::rebuildEpollLocked() {
135e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    // Close old epoll instance if we have one.
136e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (mEpollFd >= 0) {
137e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#if DEBUG_CALLBACKS
138e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this);
139e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#endif
140e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        close(mEpollFd);
141e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    }
142e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
143e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    // Allocate the new epoll instance and register the wake pipe.
144e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
1455b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
146e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
147e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    struct epoll_event eventItem;
148e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
149e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    eventItem.events = EPOLLIN;
1508892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    eventItem.data.fd = mWakeEventFd;
1518892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
1525b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s",
1535b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                        strerror(errno));
154e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
155e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    for (size_t i = 0; i < mRequests.size(); i++) {
156e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        const Request& request = mRequests.valueAt(i);
157e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        struct epoll_event eventItem;
158e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        request.initEventItem(&eventItem);
159e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
160e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
161e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        if (epollResult < 0) {
1625b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes            ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",
1635b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                  request.fd, strerror(errno));
164e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        }
165e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    }
166e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown}
167e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
168e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::scheduleEpollRebuildLocked() {
169e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (!mEpollRebuildRequired) {
170e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#if DEBUG_CALLBACKS
171e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        ALOGD("%p ~ scheduleEpollRebuildLocked - scheduling epoll set rebuild", this);
172e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown#endif
173e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        mEpollRebuildRequired = true;
174e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        wake();
175e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    }
176e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown}
177e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
1787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
1797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int result = 0;
1807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (;;) {
1817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        while (mResponseIndex < mResponses.size()) {
1827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            const Response& response = mResponses.itemAt(mResponseIndex++);
183dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            int ident = response.request.ident;
184dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            if (ident >= 0) {
1853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int fd = response.request.fd;
1863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                int events = response.events;
1873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                void* data = response.request.data;
1887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
189eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
1903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        "fd=%d, events=0x%x, data=%p",
1913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, ident, fd, events, data);
1927901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
1933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outFd != NULL) *outFd = fd;
1943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outEvents != NULL) *outEvents = events;
1953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                if (outData != NULL) *outData = data;
1963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                return ident;
1977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
1987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
1997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2007901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (result != 0) {
2017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
202eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block            ALOGD("%p ~ pollOnce - returning result %d", this, result);
2037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outFd != NULL) *outFd = 0;
205dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            if (outEvents != NULL) *outEvents = 0;
2067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (outData != NULL) *outData = NULL;
2077901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return result;
2087901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
2097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        result = pollInner(timeoutMillis);
2117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
2137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollInner(int timeoutMillis) {
2157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
216eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
2177901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2188d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Adjust the timeout based on when the next message is due.
2203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
2213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
22243550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
22343550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown        if (messageTimeoutMillis >= 0
22443550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown                && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
22543550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = messageTimeoutMillis;
2263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
2273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE
2287a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d",
2293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                this, mNextMessageUptime - now, timeoutMillis);
2303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
2313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
2323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
2333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Poll.
2341693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom    int result = POLL_WAKE;
2358d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.clear();
2368d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponseIndex = 0;
2378d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
23819159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    // We are about to idle.
23927e5721860142b1b20081b535c55e7917366385fJeff Brown    mPolling = true;
24019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
2417901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
2427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
2438d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
24419159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn    // No longer idling.
24527e5721860142b1b20081b535c55e7917366385fJeff Brown    mPolling = false;
24619159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
2473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Acquire lock.
2483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.lock();
2493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
250e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    // Rebuild epoll set if needed.
251e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (mEpollRebuildRequired) {
252e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        mEpollRebuildRequired = false;
253e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        rebuildEpollLocked();
254e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        goto Done;
255e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    }
256e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
2573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll error.
2587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount < 0) {
259171bf9e69792f4796e27334c8a97dbd8576ad78aJeff Brown        if (errno == EINTR) {
2608d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown            goto Done;
2617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
2626ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes        ALOGW("Poll failed with an unexpected error: %s", strerror(errno));
2631693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        result = POLL_ERROR;
2648d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2667901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2673e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Check for poll timeout.
2687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (eventCount == 0) {
2697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
270eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block        ALOGD("%p ~ pollOnce - timeout", this);
2717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2721693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        result = POLL_TIMEOUT;
2738d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown        goto Done;
2747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
2757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
2763e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Handle all events.
2777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
278eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
2797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
2808d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
2819da1810050d8825e51dabdd0262173432d49c16cJeff Brown    for (int i = 0; i < eventCount; i++) {
2829da1810050d8825e51dabdd0262173432d49c16cJeff Brown        int fd = eventItems[i].data.fd;
2839da1810050d8825e51dabdd0262173432d49c16cJeff Brown        uint32_t epollEvents = eventItems[i].events;
2848892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn        if (fd == mWakeEventFd) {
2859da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (epollEvents & EPOLLIN) {
2868d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                awoken();
2877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            } else {
2888892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn                ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);
2899da1810050d8825e51dabdd0262173432d49c16cJeff Brown            }
2909da1810050d8825e51dabdd0262173432d49c16cJeff Brown        } else {
2919da1810050d8825e51dabdd0262173432d49c16cJeff Brown            ssize_t requestIndex = mRequests.indexOfKey(fd);
2929da1810050d8825e51dabdd0262173432d49c16cJeff Brown            if (requestIndex >= 0) {
2939da1810050d8825e51dabdd0262173432d49c16cJeff Brown                int events = 0;
2941693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
2951693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
2961693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
2971693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
2988d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown                pushResponse(events, mRequests.valueAt(requestIndex));
2999da1810050d8825e51dabdd0262173432d49c16cJeff Brown            } else {
30061d341b8d3d771f4ef3dd54df0502b19b7a2ab4dSteve Block                ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
3019da1810050d8825e51dabdd0262173432d49c16cJeff Brown                        "no longer registered.", epollEvents, fd);
3027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3037901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3047901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3058d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff BrownDone: ;
3068d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
3073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke pending message callbacks.
3083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mNextMessageUptime = LLONG_MAX;
3093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    while (mMessageEnvelopes.size() != 0) {
3103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
3113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
3123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (messageEnvelope.uptime <= now) {
3133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // Remove the envelope from the list.
3143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // We keep a strong reference to the handler until the call to handleMessage
3153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // finishes.  Then we drop it so that the handler can be deleted *before*
3163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // we reacquire our lock.
3173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            { // obtain handler
3183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                sp<MessageHandler> handler = messageEnvelope.handler;
3193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                Message message = messageEnvelope.message;
3203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(0);
3213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mSendingMessage = true;
3223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mLock.unlock();
3233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
325eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block                ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
3263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                        this, handler.get(), message.what);
3273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
3283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                handler->handleMessage(message);
3293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            } // release handler
3303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mLock.lock();
3323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mSendingMessage = false;
3331693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            result = POLL_CALLBACK;
3343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        } else {
3353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            // The last message left at the head of the queue determines the next wakeup time.
3363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            mNextMessageUptime = messageEnvelope.uptime;
3373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            break;
3383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
3393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
3403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Release lock.
3423e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    mLock.unlock();
3433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
3443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Invoke all response callbacks.
3457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    for (size_t i = 0; i < mResponses.size(); i++) {
346dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown        Response& response = mResponses.editItemAt(i);
3471693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        if (response.request.ident == POLL_CALLBACK) {
3483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int fd = response.request.fd;
3493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            int events = response.events;
3503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            void* data = response.request.data;
3517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
352eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block            ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
353dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown                    this, response.request.callback.get(), fd, events, data);
3547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
3557a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            // Invoke the callback.  Note that the file descriptor may be closed by
3567a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            // the callback (and potentially even reused) before the function returns so
3577a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            // we need to be a little careful when removing the file descriptor afterwards.
358dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            int callbackResult = response.request.callback->handleEvent(fd, events, data);
3597901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (callbackResult == 0) {
3607a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                removeFd(fd, response.request.seq);
3617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3627a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown
363dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            // Clear the callback reference in the response structure promptly because we
364dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            // will not clear the response vector itself until the next poll.
365dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            response.request.callback.clear();
3661693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            result = POLL_CALLBACK;
3677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return result;
3707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
3717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3727901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
3737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    if (timeoutMillis <= 0) {
3747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        int result;
3757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        do {
3767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            result = pollOnce(timeoutMillis, outFd, outEvents, outData);
3771693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        } while (result == POLL_CALLBACK);
3787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        return result;
3797901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } else {
3807901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
3817901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                + milliseconds_to_nanoseconds(timeoutMillis);
3827901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3837901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        for (;;) {
3847901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
3851693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom            if (result != POLL_CALLBACK) {
3867901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return result;
3877901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3887901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
38943550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
39043550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
39143550eee5bfeaf7832487a2285ae86be0f7ce561Jeff Brown            if (timeoutMillis == 0) {
3921693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom                return POLL_TIMEOUT;
3937901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
3947901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
3957901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
3967901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
3977901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
3987901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownvoid Looper::wake() {
3997901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_POLL_AND_WAKE
400eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ wake", this);
4017901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4027901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4038892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    uint64_t inc = 1;
4048892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
4058892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    if (nWrite != sizeof(uint64_t)) {
4067901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (errno != EAGAIN) {
40748c35dbe5044ef07afda15ccc105a7018006eca6John Reck            LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s",
40848c35dbe5044ef07afda15ccc105a7018006eca6John Reck                    mWakeEventFd, strerror(errno));
4097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
4127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4138d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::awoken() {
4148d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#if DEBUG_POLL_AND_WAKE
415eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ awoken", this);
4168d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown#endif
4178d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4188892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    uint64_t counter;
4198892ce6383c7aa3e18107b94889882a0374de69fTim Kilbourn    TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
4208d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
4218d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4228d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brownvoid Looper::pushResponse(int events, const Request& request) {
4238d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    Response response;
4248d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.events = events;
4258d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    response.request = request;
4268d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    mResponses.push(response);
4278d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown}
4288d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown
4291693d7e48f976c2615100378c7e98d245e0213beBrian Carlstromint Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
430dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
431dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown}
432dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown
433dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brownint Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
4347901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
435eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
436dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            events, callback.get(), data);
4377901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
4387901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
439dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    if (!callback.get()) {
4407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (! mAllowNonCallbacks) {
4411b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block            ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
4427901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
4437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
4447901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4457901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (ident < 0) {
446dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown            ALOGE("Invalid attempt to set NULL callback with ident < 0.");
4477901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return -1;
4487901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
449dd1b0378cec939e7c90f8e8d8216b481f9f2035aJeff Brown    } else {
4501693d7e48f976c2615100378c7e98d245e0213beBrian Carlstrom        ident = POLL_CALLBACK;
4517901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    }
4527901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4537901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
4547901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
4557901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4567901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        Request request;
4577901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.fd = fd;
4587901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.ident = ident;
459e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        request.events = events;
460e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        request.seq = mNextRequestSeq++;
4617901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.callback = callback;
4627901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        request.data = data;
4637a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1
4647901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4657901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        struct epoll_event eventItem;
466e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown        request.initEventItem(&eventItem);
4677901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
4687901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
4697901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
4707901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
4717901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
4726ed68cc412752e4c78755df9a1516e610ec66fa8Elliott Hughes                ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));
4737901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown                return -1;
4747901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
4757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.add(fd, request);
4767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        } else {
4777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
4787901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            if (epollResult < 0) {
4797a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                if (errno == ENOENT) {
480e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // Tolerate ENOENT because it means that an older file descriptor was
4817a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    // closed before its callback was unregistered and meanwhile a new
4827a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    // file descriptor with the same number has been created and is now
483e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // being registered for the first time.  This error may occur naturally
484e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // when a callback has the side-effect of closing the file descriptor
485e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // before returning and unregistering itself.  Callback sequence number
486e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // checks further ensure that the race is benign.
487e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    //
488e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // Unfortunately due to kernel limitations we need to rebuild the epoll
489e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // set from scratch because it may contain an old file handle that we are
490e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // now unable to remove since its file descriptor is no longer valid.
491e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // No such problem would have occurred if we were using the poll system
492e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    // call instead, but that approach carries others disadvantages.
4937a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS
4947a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor "
4955b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                            "being recycled, falling back on EPOLL_CTL_ADD: %s",
4965b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                            this, strerror(errno));
4977a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif
4987a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
4997a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    if (epollResult < 0) {
5005b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                        ALOGE("Error modifying or adding epoll events for fd %d: %s",
5015b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                                fd, strerror(errno));
5027a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                        return -1;
5037a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    }
504e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                    scheduleEpollRebuildLocked();
5057a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                } else {
5065b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                    ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));
5077a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    return -1;
5087a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                }
5097901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            }
5107901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            mRequests.replaceValueAt(requestIndex, request);
5117901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5127901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    } // release lock
5137901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
5147901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
5157901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5167901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brownint Looper::removeFd(int fd) {
5177a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown    return removeFd(fd, -1);
5187a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown}
5197a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown
5207a0310ef678edcf06acfd230617c427a788e58f8Jeff Brownint Looper::removeFd(int fd, int seq) {
5217901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#if DEBUG_CALLBACKS
5227a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown    ALOGD("%p ~ removeFd - fd=%d, seq=%d", this, fd, seq);
5237901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown#endif
5247901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5257901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    { // acquire lock
5267901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        AutoMutex _l(mLock);
5277901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        ssize_t requestIndex = mRequests.indexOfKey(fd);
5287901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        if (requestIndex < 0) {
5297901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown            return 0;
5307901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5317901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5327a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        // Check the sequence number if one was given.
5337a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        if (seq != -1 && mRequests.valueAt(requestIndex).seq != seq) {
5347a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS
5357a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            ALOGD("%p ~ removeFd - sequence number mismatch, oldSeq=%d",
5367a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                    this, mRequests.valueAt(requestIndex).seq);
5377a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif
5387a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            return 0;
5397901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        }
5407901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5417a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        // Always remove the FD from the request map even if an error occurs while
5427a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        // updating the epoll set so that we avoid accidentally leaking callbacks.
5437901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown        mRequests.removeItemsAt(requestIndex);
5447a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown
5457a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
5467a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        if (epollResult < 0) {
5477a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            if (seq != -1 && (errno == EBADF || errno == ENOENT)) {
548e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // Tolerate EBADF or ENOENT when the sequence number is known because it
5497a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                // means that the file descriptor was closed before its callback was
550e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // unregistered.  This error may occur naturally when a callback has the
551e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // side-effect of closing the file descriptor before returning and
552e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // unregistering itself.
553e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                //
554e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // Unfortunately due to kernel limitations we need to rebuild the epoll
555e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // set from scratch because it may contain an old file handle that we are
556e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // now unable to remove since its file descriptor is no longer valid.
557e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // No such problem would have occurred if we were using the poll system
558e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                // call instead, but that approach carries others disadvantages.
5597a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#if DEBUG_CALLBACKS
5607a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                ALOGD("%p ~ removeFd - EPOLL_CTL_DEL failed due to file descriptor "
5615b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                        "being closed: %s", this, strerror(errno));
5627a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown#endif
563e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown                scheduleEpollRebuildLocked();
5647a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            } else {
56518a574f715b767ee8a2f02903c883d571b42409fJeff Brown                // Some other error occurred.  This is really weird because it means
56618a574f715b767ee8a2f02903c883d571b42409fJeff Brown                // our list of callbacks got out of sync with the epoll set somehow.
56718a574f715b767ee8a2f02903c883d571b42409fJeff Brown                // We defensively rebuild the epoll set to avoid getting spurious
56818a574f715b767ee8a2f02903c883d571b42409fJeff Brown                // notifications with nowhere to go.
5695b8ff09578e647db8575699cf46ab9f6f816f6f8Elliott Hughes                ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno));
57018a574f715b767ee8a2f02903c883d571b42409fJeff Brown                scheduleEpollRebuildLocked();
5717a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown                return -1;
5727a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown            }
5737a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown        }
5748d15c74d50fd01d6e63970aadd261a9d3bed27e7Jeff Brown    } // release lock
5757901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown    return 1;
5767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown}
5777901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown
5783e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
579aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
580aa13c1b90e5d9cae064bb425dd094ccbd411e073Jeff Brown    sendMessageAtTime(now, handler, message);
5813e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5823e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5833e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
5843e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
5853e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
5863e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    sendMessageAtTime(now + uptimeDelay, handler, message);
5873e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
5883e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5893e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
5903e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        const Message& message) {
5913e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
5927a0310ef678edcf06acfd230617c427a788e58f8Jeff Brown    ALOGD("%p ~ sendMessageAtTime - uptime=%" PRId64 ", handler=%p, what=%d",
5933e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            this, uptime, handler.get(), message.what);
5943e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
5953e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
5963e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    size_t i = 0;
5973e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
5983e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
5993e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6003e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        size_t messageCount = mMessageEnvelopes.size();
6013e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
6023e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            i += 1;
6033e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
6043e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6053e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        MessageEnvelope messageEnvelope(uptime, handler, message);
6063e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
6073e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6083e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // Optimization: If the Looper is currently sending a message, then we can skip
6093e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // the call to wake() because the next thing the Looper will do after processing
6103e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // messages is to decide when the next wakeup time should be.  In fact, it does
6113e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        // not even matter whether this code is running on the Looper thread.
6123e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        if (mSendingMessage) {
6133e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            return;
6143e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
6153e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
6163e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6173e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    // Wake the poll loop only when we enqueue a new message at the head.
6183e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    if (i == 0) {
6193e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        wake();
6203e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    }
6213e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
6223e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6233e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler) {
6243e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
625eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ removeMessages - handler=%p", this, handler.get());
6263e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
6273e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6283e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
6293e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
6303e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6313e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
6323e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
6333e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler) {
6343e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
6353e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
6363e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
6373e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
6383e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
6393e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6403e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brownvoid Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
6413e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#if DEBUG_CALLBACKS
642eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block    ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
6433e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown#endif
6443e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6453e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    { // acquire lock
6463e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        AutoMutex _l(mLock);
6473e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
6483e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
6493e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
6503e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            if (messageEnvelope.handler == handler
6513e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                    && messageEnvelope.message.what == what) {
6523e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown                mMessageEnvelopes.removeAt(i);
6533e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown            }
6543e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown        }
6553e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown    } // release lock
6563e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown}
6573e2e38bc5bbf658eb9940f72974270b11c5b84e1Jeff Brown
65827e5721860142b1b20081b535c55e7917366385fJeff Brownbool Looper::isPolling() const {
65927e5721860142b1b20081b535c55e7917366385fJeff Brown    return mPolling;
66019159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn}
66119159f90020c04ac2f4dcb39424d740f765ed9a3Dianne Hackborn
662e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brownvoid Looper::Request::initEventItem(struct epoll_event* eventItem) const {
663e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    int epollEvents = 0;
664e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (events & EVENT_INPUT) epollEvents |= EPOLLIN;
665e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT;
666e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
667e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
668e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    eventItem->events = epollEvents;
669e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown    eventItem->data.fd = fd;
670e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown}
671e7d54f80cb686026d5b0974a4b1c1ba1d4ebff64Jeff Brown
67217b5b82d64686d482e6dcf96ee54fd62234d5f27Colin CrossMessageHandler::~MessageHandler() { }
67317b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
67417b5b82d64686d482e6dcf96ee54fd62234d5f27Colin CrossLooperCallback::~LooperCallback() { }
67517b5b82d64686d482e6dcf96ee54fd62234d5f27Colin Cross
6767901eb25c60b1df00050d6c3772505d8dcfcdab9Jeff Brown} // namespace android
677