Looper::Looper(boolallowNonCallbacks):mAllowNonCallbacks(allowNonCallbacks),mSendingMessage(false),mResponseIndex(0),mNextMessageUptime(LLONG_MAX){intwakeFds[2];intresult=pipe(wakeFds);// 创建管道
LOG_ALWAYS_FATAL_IF(result!=0,"Could not create wake pipe. errno=%d",errno);mWakeReadPipeFd=wakeFds[0];mWakeWritePipeFd=wakeFds[1];result=fcntl(mWakeReadPipeFd,F_SETFL,O_NONBLOCK);LOG_ALWAYS_FATAL_IF(result!=0,"Could not make wake read pipe non-blocking. errno=%d",errno);result=fcntl(mWakeWritePipeFd,F_SETFL,O_NONBLOCK);LOG_ALWAYS_FATAL_IF(result!=0,"Could not make wake write pipe non-blocking. errno=%d",errno);mIdling=false;// Allocate the epoll instance and register the wake pipe.
mEpollFd=epoll_create(EPOLL_SIZE_HINT);// 创建 epoll 描述符
LOG_ALWAYS_FATAL_IF(mEpollFd<0,"Could not create epoll instance. errno=%d",errno);structepoll_eventeventItem;memset(&eventItem,0,sizeof(epoll_event));// zero out unused members of data field union
eventItem.events=EPOLLIN;eventItem.data.fd=mWakeReadPipeFd;result=epoll_ctl(mEpollFd,EPOLL_CTL_ADD,mWakeReadPipeFd,&eventItem);// 监听读管道中的事件
LOG_ALWAYS_FATAL_IF(result!=0,"Could not add wake read pipe to epoll instance. errno=%d",errno);}
在往 MessageQueue 中插入消息的时候会调用 wake 方法,这里就会向管道中的写描述符写入 W ,如果失败了会一直尝试,直到成功为止。
1
2
3
4
5
6
7
8
9
10
11
12
voidLooper::wake(){ssize_tnWrite;do{nWrite=write(mWakeWritePipeFd,"W",1);// 往写描述符中写入 W
}while(nWrite==-1&&errno==EINTR);if(nWrite!=1){if(errno!=EAGAIN){ALOGW("Could not write wake signal, errno=%d",errno);}}}
intLooper::pollInner(inttimeoutMillis){//...
intresult=POLL_WAKE;mResponses.clear();mResponseIndex=0;mIdling=true;structepoll_eventeventItems[EPOLL_MAX_EVENTS];// 检测监听的描述符中是否有事件
inteventCount=epoll_wait(mEpollFd,eventItems,EPOLL_MAX_EVENTS,timeoutMillis);mIdling=false;mLock.lock();// ...
for(inti=0;i<eventCount;i++){intfd=eventItems[i].data.fd;uint32_tepollEvents=eventItems[i].events;if(fd==mWakeReadPipeFd){// 判断是否是读管道描述符
if(epollEvents&EPOLLIN){awoken();// 读取管道中所有的数据
}else{ALOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.",epollEvents);}}else{ssize_trequestIndex=mRequests.indexOfKey(fd);if(requestIndex>=0){intevents=0;if(epollEvents&EPOLLIN)events|=EVENT_INPUT;if(epollEvents&EPOLLOUT)events|=EVENT_OUTPUT;if(epollEvents&EPOLLERR)events|=EVENT_ERROR;if(epollEvents&EPOLLHUP)events|=EVENT_HANGUP;pushResponse(events,mRequests.valueAt(requestIndex));}else{ALOGW("Ignoring unexpected epoll events 0x%x on fd %d that is ""no longer registered.",epollEvents,fd);}}}Done:;mNextMessageUptime=LLONG_MAX;while(mMessageEnvelopes.size()!=0){nsecs_tnow=systemTime(SYSTEM_TIME_MONOTONIC);constMessageEnvelope&messageEnvelope=mMessageEnvelopes.itemAt(0);if(messageEnvelope.uptime<=now){{// obtain handler
sp<MessageHandler>handler=messageEnvelope.handler;Messagemessage=messageEnvelope.message;mMessageEnvelopes.removeAt(0);mSendingMessage=true;mLock.unlock();handler->handleMessage(message);}// release handler
mLock.lock();mSendingMessage=false;result=POLL_CALLBACK;}else{// The last message left at the head of the queue determines the next wakeup time.
mNextMessageUptime=messageEnvelope.uptime;break;}}// Release lock.
mLock.unlock();// ...
returnresult;}voidLooper::awoken(){charbuffer[16];ssize_tnRead;do{nRead=read(mWakeReadPipeFd,buffer,sizeof(buffer));// 从管道中读取数据
}while((nRead==-1&&errno==EINTR)||nRead==sizeof(buffer));}