Home | History | Annotate | Download | only in libutils
      1 //
      2 // Copyright 2010 The Android Open Source Project
      3 //
      4 // A looper implementation based on epoll().
      5 //
      6 #define LOG_TAG "Looper"
      7 
      8 //#define LOG_NDEBUG 0
      9 
     10 // Debugs poll and wake interactions.
     11 #define DEBUG_POLL_AND_WAKE 0
     12 
     13 // Debugs callback registration and invocation.
     14 #define DEBUG_CALLBACKS 0
     15 
     16 #include <utils/Looper.h>
     17 #include <sys/eventfd.h>
     18 
     19 namespace android {
     20 
     21 // --- WeakMessageHandler ---
     22 
     23 WeakMessageHandler::WeakMessageHandler(const wp<MessageHandler>& handler) :
     24         mHandler(handler) {
     25 }
     26 
     27 WeakMessageHandler::~WeakMessageHandler() {
     28 }
     29 
     30 void WeakMessageHandler::handleMessage(const Message& message) {
     31     sp<MessageHandler> handler = mHandler.promote();
     32     if (handler != NULL) {
     33         handler->handleMessage(message);
     34     }
     35 }
     36 
     37 
     38 // --- SimpleLooperCallback ---
     39 
     40 SimpleLooperCallback::SimpleLooperCallback(Looper_callbackFunc callback) :
     41         mCallback(callback) {
     42 }
     43 
     44 SimpleLooperCallback::~SimpleLooperCallback() {
     45 }
     46 
     47 int SimpleLooperCallback::handleEvent(int fd, int events, void* data) {
     48     return mCallback(fd, events, data);
     49 }
     50 
     51 
     52 // --- Looper ---
     53 
     54 // Hint for number of file descriptors to be associated with the epoll instance.
     55 static const int EPOLL_SIZE_HINT = 8;
     56 
     57 // Maximum number of file descriptors for which to retrieve poll events each iteration.
     58 static const int EPOLL_MAX_EVENTS = 16;
     59 
     60 static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
     61 static pthread_key_t gTLSKey = 0;
     62 
     63 Looper::Looper(bool allowNonCallbacks) :
     64         mAllowNonCallbacks(allowNonCallbacks), mSendingMessage(false),
     65         mPolling(false), mEpollFd(-1), mEpollRebuildRequired(false),
     66         mNextRequestSeq(0), mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
     67     mWakeEventFd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
     68     LOG_ALWAYS_FATAL_IF(mWakeEventFd < 0, "Could not make wake event fd: %s",
     69                         strerror(errno));
     70 
     71     AutoMutex _l(mLock);
     72     rebuildEpollLocked();
     73 }
     74 
     75 Looper::~Looper() {
     76     close(mWakeEventFd);
     77     mWakeEventFd = -1;
     78     if (mEpollFd >= 0) {
     79         close(mEpollFd);
     80     }
     81 }
     82 
     83 void Looper::initTLSKey() {
     84     int result = pthread_key_create(& gTLSKey, threadDestructor);
     85     LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
     86 }
     87 
     88 void Looper::threadDestructor(void *st) {
     89     Looper* const self = static_cast<Looper*>(st);
     90     if (self != NULL) {
     91         self->decStrong((void*)threadDestructor);
     92     }
     93 }
     94 
     95 void Looper::setForThread(const sp<Looper>& looper) {
     96     sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
     97 
     98     if (looper != NULL) {
     99         looper->incStrong((void*)threadDestructor);
    100     }
    101 
    102     pthread_setspecific(gTLSKey, looper.get());
    103 
    104     if (old != NULL) {
    105         old->decStrong((void*)threadDestructor);
    106     }
    107 }
    108 
    109 sp<Looper> Looper::getForThread() {
    110     int result = pthread_once(& gTLSOnce, initTLSKey);
    111     LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
    112 
    113     return (Looper*)pthread_getspecific(gTLSKey);
    114 }
    115 
    116 sp<Looper> Looper::prepare(int opts) {
    117     bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
    118     sp<Looper> looper = Looper::getForThread();
    119     if (looper == NULL) {
    120         looper = new Looper(allowNonCallbacks);
    121         Looper::setForThread(looper);
    122     }
    123     if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
    124         ALOGW("Looper already prepared for this thread with a different value for the "
    125                 "LOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
    126     }
    127     return looper;
    128 }
    129 
    130 bool Looper::getAllowNonCallbacks() const {
    131     return mAllowNonCallbacks;
    132 }
    133 
    134 void Looper::rebuildEpollLocked() {
    135     // Close old epoll instance if we have one.
    136     if (mEpollFd >= 0) {
    137 #if DEBUG_CALLBACKS
    138         ALOGD("%p ~ rebuildEpollLocked - rebuilding epoll set", this);
    139 #endif
    140         close(mEpollFd);
    141     }
    142 
    143     // Allocate the new epoll instance and register the wake pipe.
    144     mEpollFd = epoll_create(EPOLL_SIZE_HINT);
    145     LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
    146 
    147     struct epoll_event eventItem;
    148     memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
    149     eventItem.events = EPOLLIN;
    150     eventItem.data.fd = mWakeEventFd;
    151     int result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeEventFd, & eventItem);
    152     LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake event fd to epoll instance: %s",
    153                         strerror(errno));
    154 
    155     for (size_t i = 0; i < mRequests.size(); i++) {
    156         const Request& request = mRequests.valueAt(i);
    157         struct epoll_event eventItem;
    158         request.initEventItem(&eventItem);
    159 
    160         int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, request.fd, & eventItem);
    161         if (epollResult < 0) {
    162             ALOGE("Error adding epoll events for fd %d while rebuilding epoll set: %s",
    163                   request.fd, strerror(errno));
    164         }
    165     }
    166 }
    167 
    168 void Looper::scheduleEpollRebuildLocked() {
    169     if (!mEpollRebuildRequired) {
    170 #if DEBUG_CALLBACKS
    171         ALOGD("%p ~ scheduleEpollRebuildLocked - scheduling epoll set rebuild", this);
    172 #endif
    173         mEpollRebuildRequired = true;
    174         wake();
    175     }
    176 }
    177 
    178 int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    179     int result = 0;
    180     for (;;) {
    181         while (mResponseIndex < mResponses.size()) {
    182             const Response& response = mResponses.itemAt(mResponseIndex++);
    183             int ident = response.request.ident;
    184             if (ident >= 0) {
    185                 int fd = response.request.fd;
    186                 int events = response.events;
    187                 void* data = response.request.data;
    188 #if DEBUG_POLL_AND_WAKE
    189                 ALOGD("%p ~ pollOnce - returning signalled identifier %d: "
    190                         "fd=%d, events=0x%x, data=%p",
    191                         this, ident, fd, events, data);
    192 #endif
    193                 if (outFd != NULL) *outFd = fd;
    194                 if (outEvents != NULL) *outEvents = events;
    195                 if (outData != NULL) *outData = data;
    196                 return ident;
    197             }
    198         }
    199 
    200         if (result != 0) {
    201 #if DEBUG_POLL_AND_WAKE
    202             ALOGD("%p ~ pollOnce - returning result %d", this, result);
    203 #endif
    204             if (outFd != NULL) *outFd = 0;
    205             if (outEvents != NULL) *outEvents = 0;
    206             if (outData != NULL) *outData = NULL;
    207             return result;
    208         }
    209 
    210         result = pollInner(timeoutMillis);
    211     }
    212 }
    213 
    214 int Looper::pollInner(int timeoutMillis) {
    215 #if DEBUG_POLL_AND_WAKE
    216     ALOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
    217 #endif
    218 
    219     // Adjust the timeout based on when the next message is due.
    220     if (timeoutMillis != 0 && mNextMessageUptime != LLONG_MAX) {
    221         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    222         int messageTimeoutMillis = toMillisecondTimeoutDelay(now, mNextMessageUptime);
    223         if (messageTimeoutMillis >= 0
    224                 && (timeoutMillis < 0 || messageTimeoutMillis < timeoutMillis)) {
    225             timeoutMillis = messageTimeoutMillis;
    226         }
    227 #if DEBUG_POLL_AND_WAKE
    228         ALOGD("%p ~ pollOnce - next message in %" PRId64 "ns, adjusted timeout: timeoutMillis=%d",
    229                 this, mNextMessageUptime - now, timeoutMillis);
    230 #endif
    231     }
    232 
    233     // Poll.
    234     int result = POLL_WAKE;
    235     mResponses.clear();
    236     mResponseIndex = 0;
    237 
    238     // We are about to idle.
    239     mPolling = true;
    240 
    241     struct epoll_event eventItems[EPOLL_MAX_EVENTS];
    242     int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
    243 
    244     // No longer idling.
    245     mPolling = false;
    246 
    247     // Acquire lock.
    248     mLock.lock();
    249 
    250     // Rebuild epoll set if needed.
    251     if (mEpollRebuildRequired) {
    252         mEpollRebuildRequired = false;
    253         rebuildEpollLocked();
    254         goto Done;
    255     }
    256 
    257     // Check for poll error.
    258     if (eventCount < 0) {
    259         if (errno == EINTR) {
    260             goto Done;
    261         }
    262         ALOGW("Poll failed with an unexpected error: %s", strerror(errno));
    263         result = POLL_ERROR;
    264         goto Done;
    265     }
    266 
    267     // Check for poll timeout.
    268     if (eventCount == 0) {
    269 #if DEBUG_POLL_AND_WAKE
    270         ALOGD("%p ~ pollOnce - timeout", this);
    271 #endif
    272         result = POLL_TIMEOUT;
    273         goto Done;
    274     }
    275 
    276     // Handle all events.
    277 #if DEBUG_POLL_AND_WAKE
    278     ALOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
    279 #endif
    280 
    281     for (int i = 0; i < eventCount; i++) {
    282         int fd = eventItems[i].data.fd;
    283         uint32_t epollEvents = eventItems[i].events;
    284         if (fd == mWakeEventFd) {
    285             if (epollEvents & EPOLLIN) {
    286                 awoken();
    287             } else {
    288                 ALOGW("Ignoring unexpected epoll events 0x%x on wake event fd.", epollEvents);
    289             }
    290         } else {
    291             ssize_t requestIndex = mRequests.indexOfKey(fd);
    292             if (requestIndex >= 0) {
    293                 int events = 0;
    294                 if (epollEvents & EPOLLIN) events |= EVENT_INPUT;
    295                 if (epollEvents & EPOLLOUT) events |= EVENT_OUTPUT;
    296                 if (epollEvents & EPOLLERR) events |= EVENT_ERROR;
    297                 if (epollEvents & EPOLLHUP) events |= EVENT_HANGUP;
    298                 pushResponse(events, mRequests.valueAt(requestIndex));
    299             } else {
    300                 ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
    301                         "no longer registered.", epollEvents, fd);
    302             }
    303         }
    304     }
    305 Done: ;
    306 
    307     // Invoke pending message callbacks.
    308     mNextMessageUptime = LLONG_MAX;
    309     while (mMessageEnvelopes.size() != 0) {
    310         nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    311         const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(0);
    312         if (messageEnvelope.uptime <= now) {
    313             // Remove the envelope from the list.
    314             // We keep a strong reference to the handler until the call to handleMessage
    315             // finishes.  Then we drop it so that the handler can be deleted *before*
    316             // we reacquire our lock.
    317             { // obtain handler
    318                 sp<MessageHandler> handler = messageEnvelope.handler;
    319                 Message message = messageEnvelope.message;
    320                 mMessageEnvelopes.removeAt(0);
    321                 mSendingMessage = true;
    322                 mLock.unlock();
    323 
    324 #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
    325                 ALOGD("%p ~ pollOnce - sending message: handler=%p, what=%d",
    326                         this, handler.get(), message.what);
    327 #endif
    328                 handler->handleMessage(message);
    329             } // release handler
    330 
    331             mLock.lock();
    332             mSendingMessage = false;
    333             result = POLL_CALLBACK;
    334         } else {
    335             // The last message left at the head of the queue determines the next wakeup time.
    336             mNextMessageUptime = messageEnvelope.uptime;
    337             break;
    338         }
    339     }
    340 
    341     // Release lock.
    342     mLock.unlock();
    343 
    344     // Invoke all response callbacks.
    345     for (size_t i = 0; i < mResponses.size(); i++) {
    346         Response& response = mResponses.editItemAt(i);
    347         if (response.request.ident == POLL_CALLBACK) {
    348             int fd = response.request.fd;
    349             int events = response.events;
    350             void* data = response.request.data;
    351 #if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
    352             ALOGD("%p ~ pollOnce - invoking fd event callback %p: fd=%d, events=0x%x, data=%p",
    353                     this, response.request.callback.get(), fd, events, data);
    354 #endif
    355             // Invoke the callback.  Note that the file descriptor may be closed by
    356             // the callback (and potentially even reused) before the function returns so
    357             // we need to be a little careful when removing the file descriptor afterwards.
    358             int callbackResult = response.request.callback->handleEvent(fd, events, data);
    359             if (callbackResult == 0) {
    360                 removeFd(fd, response.request.seq);
    361             }
    362 
    363             // Clear the callback reference in the response structure promptly because we
    364             // will not clear the response vector itself until the next poll.
    365             response.request.callback.clear();
    366             result = POLL_CALLBACK;
    367         }
    368     }
    369     return result;
    370 }
    371 
    372 int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
    373     if (timeoutMillis <= 0) {
    374         int result;
    375         do {
    376             result = pollOnce(timeoutMillis, outFd, outEvents, outData);
    377         } while (result == POLL_CALLBACK);
    378         return result;
    379     } else {
    380         nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
    381                 + milliseconds_to_nanoseconds(timeoutMillis);
    382 
    383         for (;;) {
    384             int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
    385             if (result != POLL_CALLBACK) {
    386                 return result;
    387             }
    388 
    389             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    390             timeoutMillis = toMillisecondTimeoutDelay(now, endTime);
    391             if (timeoutMillis == 0) {
    392                 return POLL_TIMEOUT;
    393             }
    394         }
    395     }
    396 }
    397 
    398 void Looper::wake() {
    399 #if DEBUG_POLL_AND_WAKE
    400     ALOGD("%p ~ wake", this);
    401 #endif
    402 
    403     uint64_t inc = 1;
    404     ssize_t nWrite = TEMP_FAILURE_RETRY(write(mWakeEventFd, &inc, sizeof(uint64_t)));
    405     if (nWrite != sizeof(uint64_t)) {
    406         if (errno != EAGAIN) {
    407             LOG_ALWAYS_FATAL("Could not write wake signal to fd %d: %s",
    408                     mWakeEventFd, strerror(errno));
    409         }
    410     }
    411 }
    412 
    413 void Looper::awoken() {
    414 #if DEBUG_POLL_AND_WAKE
    415     ALOGD("%p ~ awoken", this);
    416 #endif
    417 
    418     uint64_t counter;
    419     TEMP_FAILURE_RETRY(read(mWakeEventFd, &counter, sizeof(uint64_t)));
    420 }
    421 
    422 void Looper::pushResponse(int events, const Request& request) {
    423     Response response;
    424     response.events = events;
    425     response.request = request;
    426     mResponses.push(response);
    427 }
    428 
    429 int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
    430     return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : NULL, data);
    431 }
    432 
    433 int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
    434 #if DEBUG_CALLBACKS
    435     ALOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
    436             events, callback.get(), data);
    437 #endif
    438 
    439     if (!callback.get()) {
    440         if (! mAllowNonCallbacks) {
    441             ALOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
    442             return -1;
    443         }
    444 
    445         if (ident < 0) {
    446             ALOGE("Invalid attempt to set NULL callback with ident < 0.");
    447             return -1;
    448         }
    449     } else {
    450         ident = POLL_CALLBACK;
    451     }
    452 
    453     { // acquire lock
    454         AutoMutex _l(mLock);
    455 
    456         Request request;
    457         request.fd = fd;
    458         request.ident = ident;
    459         request.events = events;
    460         request.seq = mNextRequestSeq++;
    461         request.callback = callback;
    462         request.data = data;
    463         if (mNextRequestSeq == -1) mNextRequestSeq = 0; // reserve sequence number -1
    464 
    465         struct epoll_event eventItem;
    466         request.initEventItem(&eventItem);
    467 
    468         ssize_t requestIndex = mRequests.indexOfKey(fd);
    469         if (requestIndex < 0) {
    470             int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
    471             if (epollResult < 0) {
    472                 ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));
    473                 return -1;
    474             }
    475             mRequests.add(fd, request);
    476         } else {
    477             int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
    478             if (epollResult < 0) {
    479                 if (errno == ENOENT) {
    480                     // Tolerate ENOENT because it means that an older file descriptor was
    481                     // closed before its callback was unregistered and meanwhile a new
    482                     // file descriptor with the same number has been created and is now
    483                     // being registered for the first time.  This error may occur naturally
    484                     // when a callback has the side-effect of closing the file descriptor
    485                     // before returning and unregistering itself.  Callback sequence number
    486                     // checks further ensure that the race is benign.
    487                     //
    488                     // Unfortunately due to kernel limitations we need to rebuild the epoll
    489                     // set from scratch because it may contain an old file handle that we are
    490                     // now unable to remove since its file descriptor is no longer valid.
    491                     // No such problem would have occurred if we were using the poll system
    492                     // call instead, but that approach carries others disadvantages.
    493 #if DEBUG_CALLBACKS
    494                     ALOGD("%p ~ addFd - EPOLL_CTL_MOD failed due to file descriptor "
    495                             "being recycled, falling back on EPOLL_CTL_ADD: %s",
    496                             this, strerror(errno));
    497 #endif
    498                     epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
    499                     if (epollResult < 0) {
    500                         ALOGE("Error modifying or adding epoll events for fd %d: %s",
    501                                 fd, strerror(errno));
    502                         return -1;
    503                     }
    504                     scheduleEpollRebuildLocked();
    505                 } else {
    506                     ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));
    507                     return -1;
    508                 }
    509             }
    510             mRequests.replaceValueAt(requestIndex, request);
    511         }
    512     } // release lock
    513     return 1;
    514 }
    515 
    516 int Looper::removeFd(int fd) {
    517     return removeFd(fd, -1);
    518 }
    519 
    520 int Looper::removeFd(int fd, int seq) {
    521 #if DEBUG_CALLBACKS
    522     ALOGD("%p ~ removeFd - fd=%d, seq=%d", this, fd, seq);
    523 #endif
    524 
    525     { // acquire lock
    526         AutoMutex _l(mLock);
    527         ssize_t requestIndex = mRequests.indexOfKey(fd);
    528         if (requestIndex < 0) {
    529             return 0;
    530         }
    531 
    532         // Check the sequence number if one was given.
    533         if (seq != -1 && mRequests.valueAt(requestIndex).seq != seq) {
    534 #if DEBUG_CALLBACKS
    535             ALOGD("%p ~ removeFd - sequence number mismatch, oldSeq=%d",
    536                     this, mRequests.valueAt(requestIndex).seq);
    537 #endif
    538             return 0;
    539         }
    540 
    541         // Always remove the FD from the request map even if an error occurs while
    542         // updating the epoll set so that we avoid accidentally leaking callbacks.
    543         mRequests.removeItemsAt(requestIndex);
    544 
    545         int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
    546         if (epollResult < 0) {
    547             if (seq != -1 && (errno == EBADF || errno == ENOENT)) {
    548                 // Tolerate EBADF or ENOENT when the sequence number is known because it
    549                 // means that the file descriptor was closed before its callback was
    550                 // unregistered.  This error may occur naturally when a callback has the
    551                 // side-effect of closing the file descriptor before returning and
    552                 // unregistering itself.
    553                 //
    554                 // Unfortunately due to kernel limitations we need to rebuild the epoll
    555                 // set from scratch because it may contain an old file handle that we are
    556                 // now unable to remove since its file descriptor is no longer valid.
    557                 // No such problem would have occurred if we were using the poll system
    558                 // call instead, but that approach carries others disadvantages.
    559 #if DEBUG_CALLBACKS
    560                 ALOGD("%p ~ removeFd - EPOLL_CTL_DEL failed due to file descriptor "
    561                         "being closed: %s", this, strerror(errno));
    562 #endif
    563                 scheduleEpollRebuildLocked();
    564             } else {
    565                 // Some other error occurred.  This is really weird because it means
    566                 // our list of callbacks got out of sync with the epoll set somehow.
    567                 // We defensively rebuild the epoll set to avoid getting spurious
    568                 // notifications with nowhere to go.
    569                 ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno));
    570                 scheduleEpollRebuildLocked();
    571                 return -1;
    572             }
    573         }
    574     } // release lock
    575     return 1;
    576 }
    577 
    578 void Looper::sendMessage(const sp<MessageHandler>& handler, const Message& message) {
    579     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    580     sendMessageAtTime(now, handler, message);
    581 }
    582 
    583 void Looper::sendMessageDelayed(nsecs_t uptimeDelay, const sp<MessageHandler>& handler,
    584         const Message& message) {
    585     nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
    586     sendMessageAtTime(now + uptimeDelay, handler, message);
    587 }
    588 
    589 void Looper::sendMessageAtTime(nsecs_t uptime, const sp<MessageHandler>& handler,
    590         const Message& message) {
    591 #if DEBUG_CALLBACKS
    592     ALOGD("%p ~ sendMessageAtTime - uptime=%" PRId64 ", handler=%p, what=%d",
    593             this, uptime, handler.get(), message.what);
    594 #endif
    595 
    596     size_t i = 0;
    597     { // acquire lock
    598         AutoMutex _l(mLock);
    599 
    600         size_t messageCount = mMessageEnvelopes.size();
    601         while (i < messageCount && uptime >= mMessageEnvelopes.itemAt(i).uptime) {
    602             i += 1;
    603         }
    604 
    605         MessageEnvelope messageEnvelope(uptime, handler, message);
    606         mMessageEnvelopes.insertAt(messageEnvelope, i, 1);
    607 
    608         // Optimization: If the Looper is currently sending a message, then we can skip
    609         // the call to wake() because the next thing the Looper will do after processing
    610         // messages is to decide when the next wakeup time should be.  In fact, it does
    611         // not even matter whether this code is running on the Looper thread.
    612         if (mSendingMessage) {
    613             return;
    614         }
    615     } // release lock
    616 
    617     // Wake the poll loop only when we enqueue a new message at the head.
    618     if (i == 0) {
    619         wake();
    620     }
    621 }
    622 
    623 void Looper::removeMessages(const sp<MessageHandler>& handler) {
    624 #if DEBUG_CALLBACKS
    625     ALOGD("%p ~ removeMessages - handler=%p", this, handler.get());
    626 #endif
    627 
    628     { // acquire lock
    629         AutoMutex _l(mLock);
    630 
    631         for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
    632             const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
    633             if (messageEnvelope.handler == handler) {
    634                 mMessageEnvelopes.removeAt(i);
    635             }
    636         }
    637     } // release lock
    638 }
    639 
    640 void Looper::removeMessages(const sp<MessageHandler>& handler, int what) {
    641 #if DEBUG_CALLBACKS
    642     ALOGD("%p ~ removeMessages - handler=%p, what=%d", this, handler.get(), what);
    643 #endif
    644 
    645     { // acquire lock
    646         AutoMutex _l(mLock);
    647 
    648         for (size_t i = mMessageEnvelopes.size(); i != 0; ) {
    649             const MessageEnvelope& messageEnvelope = mMessageEnvelopes.itemAt(--i);
    650             if (messageEnvelope.handler == handler
    651                     && messageEnvelope.message.what == what) {
    652                 mMessageEnvelopes.removeAt(i);
    653             }
    654         }
    655     } // release lock
    656 }
    657 
    658 bool Looper::isPolling() const {
    659     return mPolling;
    660 }
    661 
    662 void Looper::Request::initEventItem(struct epoll_event* eventItem) const {
    663     int epollEvents = 0;
    664     if (events & EVENT_INPUT) epollEvents |= EPOLLIN;
    665     if (events & EVENT_OUTPUT) epollEvents |= EPOLLOUT;
    666 
    667     memset(eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
    668     eventItem->events = epollEvents;
    669     eventItem->data.fd = fd;
    670 }
    671 
    672 MessageHandler::~MessageHandler() { }
    673 
    674 LooperCallback::~LooperCallback() { }
    675 
    676 } // namespace android
    677