Awara 2017-04-20
page11
我们来看一下SurfaceFlinger的onFirstRef函数的定义:
1voidEventThread::onFirstRef(){
2run("EventThread",PRIORITY_URGENT_DISPLAY+PRIORITY_MORE_FAVORABLE);
3}
我靠,又调用run函数,这会导致又启动了一个线程.
同样的,这也会导致readyToRun和threadLoop函数的.
EventThread的readyToRun函数是从Thread类继承而来的,是个空函数.
而EventThread的threadLoop函数的定义如下:
1boolEventThread::threadLoop(){
2DisplayEventReceiver::Eventevent;
3Vector<sp<EventThread::Connection>>signalConnections;
4signalConnections=waitForEvent(&event);
5
6//dispatcheventstolisteners...
7constsize_tcount=signalConnections.size();
8for(size_ti=0;i<count;i++){
9constsp<Connection>&conn(signalConnections[i]);
10//nowseeifwestillneedtoreportthisevent
11status_terr=conn->postEvent(event);
12if(err==-EAGAIN||err==-EWOULDBLOCK){
13//Thedestinationdoesn'taccepteventsanymore,it'sprobably
14//full.Fornow,wejustdroptheeventsonthefloor.
15//FIXME:Notethatsomeeventscannotbedroppedandwouldhave
16//tobere-sentlater.
17//Right-nowwedon'thavetheabilitytodothis.
18ALOGW("EventThread:droppingevent(%08x)forconnection%p",
19event.header.type,conn.get());
20}elseif(err<0){
21//handleanyothererroronthepipeasfatal.theonly
22//reasonablethingtodoistoclean-upthisconnection.
23//Themostcommonerrorwe'llgethereis-EPIPE.
24removeDisplayEventConnection(signalConnections[i]);
25}
26}
27returntrue;
28}
EventThread的threadLoop函数的主要逻辑就是不停地等待事件,然后交给Connection去处理.
page12
我们来分析一下MessageQueue的setEventThread函数的逻辑实现,setEventThread函数的定义如下所示:
1voidMessageQueue::setEventThread(constsp<EventThread>&eventThread)
2{
3mEventThread=eventThread;
4mEvents=eventThread->createEventConnection();
5mEventTube=mEvents->getDataChannel();
6mLooper->addFd(mEventTube->getFd(),0,ALOOPER_EVENT_INPUT,MessageQueue::cb_eventReceiver,this);
7}
第4行(MessageQueue->setEventThread)会调用EventThread的createEventConnection函数,关于createEventConnection函数的详细分析可以参考page13文件.
第5行(MessageQueue->setEventThread)会调用Connection的getDataChannel来得到一个BitTube对象并初始化,getDataChannel函数的定义如下所示:
sp<BitTube>EventThread::Connection::getDataChannel()const{
returnmChannel;
}
第6行(MessageQueue->setEventThread)会首先调用BitTube的getFd函数来得到一个文件操作符,并加入到MessageQueue的Looper里.
我们先看一下BitTube的getFd函数的定义,如下所示:
intBitTube::getFd()const
{
returnmReceiveFd;
}
BitTube的getFd函数会返回用于接受的文件操作符,这样当有数据写入该文件操作符的时候就会唤醒这个Looper处理该消息,也就是说EventThread线程收到事件会交给SurfaceFlinger的Main线程取处理了,这样就把EventThread线程和Main线程绑定到一起了.
EventThread发过来的消息的处理函数是调用的MessageQueue的cb_eventReceiver函数,关于cb_eventReceiver函数的详细分析可以参考page14文件.
page13
在这里,我们看一下EventThread的createEventConnection函数的具体实现,createEventConnection函数的定义如下:
sp<EventThread::Connection>EventThread::createEventConnection()const{
returnnewConnection(const_cast<EventThread*>(this));
}
createEventConnection函数只是返回了一个Connection对象.
Connection类的构造函数的定义如下:
EventThread::Connection::Connection(
constsp<EventThread>&eventThread)
:count(-1),mEventThread(eventThread),mChannel(newBitTube())
{
}
可以看到,Connection的mChannel会用一个BitTube来初始化,BitTube的类的声明如下:
classBitTube:publicRefBase
BitTube类的构造函数的定义如下:
1BitTube::BitTube()
2:mSendFd(-1),mReceiveFd(-1)
3{
4intsockets[2];
5if(socketpair(AF_UNIX,SOCK_SEQPACKET,0,sockets)==0){
6intsize=SOCKET_BUFFER_SIZE;
7setsockopt(sockets[0],SOL_SOCKET,SO_SNDBUF,&size,sizeof(size));
8setsockopt(sockets[0],SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));
9setsockopt(sockets[1],SOL_SOCKET,SO_SNDBUF,&size,sizeof(size));
10setsockopt(sockets[1],SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));
11fcntl(sockets[0],F_SETFL,O_NONBLOCK);
12fcntl(sockets[1],F_SETFL,O_NONBLOCK);
13mReceiveFd=sockets[0];
14mSendFd=sockets[1];
15}else{
16mReceiveFd=-errno;
17ALOGE("BitTube:pipecreationfailed(%s)",strerror(-mReceiveFd));
18}
19}
可以看出,BitTube构造函数只是创建了两个文件操作符,一个用户读,一个用于写.
page14
在这篇文章里,我们分析一下MessageQueue的cb_eventReceiver函数的实现:
intMessageQueue::cb_eventReceiver(intfd,intevents,void*data){
MessageQueue*queue=reinterpret_cast<MessageQueue*>(data);
returnqueue->eventReceiver(fd,events);
}
cb_eventReceiver函数又会调用eventReceiver函数,MessageQueue的eventReceiver函数的定义如下:
1intMessageQueue::eventReceiver(intfd,intevents){
2ssize_tn;
3DisplayEventReceiver::Eventbuffer[8];
4while((n=DisplayEventReceiver::getEvents(mEventTube,buffer,)>0){
5for(inti=0;i<n;i++){
6if(buffer[i].header.type==DisplayEventReceiver::DISPLAY_EVENT_VSYNC){
7#ifINVALIDATE_ON_VSYNC
8mHandler->dispatchInvalidate();
9#else
10mHandler->dispatchRefresh();
11#endif
12break;
13}
14}
15}
16return1;
17}
第4行(MessageQueue->eventReceiver)会在mEventTube上调用DisplayEventReceiver的getEvents函数,关于DisplayEventReceiver的getEvents函数的详细分析可以参考page15文件.
page15
在这篇文章里,我们分析一下DisplayEventReceiver的getEvents函数的实现:
1ssize_tDisplayEventReceiver::getEvents(DisplayEventReceiver::Event*events,size_tcount){
2returnDisplayEventReceiver::getEvents(mDataChannel,events,count);
3}
两个参数的getEvents又会调用三个参数的重载版本,该函数的定义如下:
1ssize_tDisplayEventReceiver::getEvents(constsp<BitTube>&dataChannel,Event*events,size_tcount)
2{
3returnBitTube::recvObjects(dataChannel,events,count);
4}
getEvents函数最终会调用BitTube的recvObjects函数,而传入的文件操作符正是成员变量mEventTube.
BitTube的recvObjects函数的定义如下:
1ssize_tBitTube::recvObjects(constsp<BitTube>&tube,void*events,size_tcount,size_tobjSize)
2{
3ssize_tnumObjects=0;
4for(size_ti=0;i<count;i++){
5char*vaddr=reinterpret_cast<char*>(events)+objSize*i;
6ssize_tsize=tube->read(vaddr,objSize);
7if(size<0){
8//erroroccurred
9returnsize;
10}elseif(size==0){
11//nomoremessages
12break;
13}
14numObjects++;
15}
16returnnumObjects;
17}
第6行(BitTube->recvObjects)会在该BitTube上调用read函数来接受数据,BitTube的read函数的定义如下所示:
1ssize_tBitTube::read(void*vaddr,size_tsize)
2{
3ssize_terr,len;
4do{
5len=::recv(mReceiveFd,vaddr,size,MSG_DONTWAIT);
6err=len<0?errno:0;
7}while(err==EINTR);
8if(err==EAGAIN||err==EWOULDBLOCK){
9//EAGAINmeansthatwehavenon-blockingI/Obuttherewas
10//nodatatoberead.Nothingtheclientshouldcareabout.
11return0;
12}
13returnerr==0?len:-err;
14}
第5行(BitTube->read)会在mReceiveFd文件操作符上读取size大小的数据,并保存到地址vaddr里去.