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