Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(2)
这个函数虽然很长,但是主要调用了talkWithDriver函数来与Binder驱动程序进行交互: status_tIPCThreadState::talkWithDriver(booldoReceive) { LOG_ASSERT(mProcess->mDriverFD>=0,"Binderdriverisnotopened"); binder_write_readbwr; //Isthereadbufferempty? constboolneedRead=mIn.dataPosition()>=mIn.dataSize(); //Wedon'twanttowriteanythingifwearestillreading //fromdataleftintheinputbufferandthecaller //hasrequestedtoreadthenextdata. constsize_toutAvail=(!doReceive||needRead)?mOut.dataSize():0; bwr.write_size=outAvail; bwr.write_buffer=(longunsignedint)mOut.data(); //Thisiswhatwe'llread. if(doReceive&&needRead){ bwr.read_size=mIn.dataCapacity(); bwr.read_buffer=(longunsignedint)mIn.data(); }else{ bwr.read_size=0; } IF_LOG_COMMANDS(){ TextOutput::Bundle_b(alog); if(outAvail!=0){ alog<<"Sendingcommandstodriver:"<<indent; constvoid*cmds=(constvoid*)bwr.write_buffer; constvoid*end=((constuint8_t*)cmds)+bwr.write_size; alog<<HexDump(cmds,bwr.write_size)<<endl; while(cmds<end)cmds=printCommand(alog,cmds); alog<<dedent; } alog<<"Sizeofreceivebuffer:"<<bwr.read_size <<",needRead:"<<needRead<<",doReceive:"<<doReceive<<endl; } //Returnimmediatelyifthereisnothingtodo. if((bwr.write_size==0)&&(bwr.read_size==0))returnNO_ERROR; bwr.write_consumed=0; bwr.read_consumed=0; status_terr; do{ IF_LOG_COMMANDS(){ alog<<"Abouttoread/write,writesize="<<mOut.dataSize()<<endl; } #ifdefined(HAVE_ANDROID_OS) if(ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr)>=0) err=NO_ERROR; else err=-errno; #else err=INVALID_OPERATION; #endif IF_LOG_COMMANDS(){ alog<<"Finishedread/write,writesize="<<mOut.dataSize()<<endl; } }while(err==-EINTR); IF_LOG_COMMANDS(){ alog<<"Ourerr:"<<(void*)err<<",writeconsumed:" <<bwr.write_consumed<<"(of"<<mOut.dataSize() <<"),readconsumed:"<<bwr.read_consumed<<endl; } if(err>=NO_ERROR){ if(bwr.write_consumed>0){ if(bwr.write_consumed<(ssize_t)mOut.dataSize()) mOut.remove(0,bwr.write_consumed); else mOut.setDataSize(0); } if(bwr.read_consumed>0){ mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); } IF_LOG_COMMANDS(){ TextOutput::Bundle_b(alog); alog<<"Remainingdatasize:"<<mOut.dataSize()<<endl; alog<<"Receivedcommandsfromdriver:"<<indent; constvoid*cmds=mIn.data(); constvoid*end=mIn.data()+mIn.dataSize(); alog<<HexDump(cmds,mIn.dataSize())<<endl; while(cmds<end)cmds=printReturnCommand(alog,cmds); alog<<dedent; } returnNO_ERROR; } returnerr; } 这里doReceive和needRead均为1,有兴趣的读者可以自已分析一下。因此,这里告诉Binder驱动程序,先执行write操作,再执行read操作,下面我们将会看到。 最后,通过ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进行到Binder驱动程序的binder_ioctl函数,我们只关注cmd为BINDER_WRITE_READ的逻辑: staticlongbinder_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg) { intret; structbinder_proc*proc=filp->private_data; structbinder_thread*thread; unsignedintsize=_IOC_SIZE(cmd); void__user*ubuf=(void__user*)arg; /*printk(KERN_INFO"binder_ioctl:%d:%d%x%lx\n",proc->pid,current->pid,cmd,arg);*/ ret=wait_event_interruptible(binder_user_error_wait,binder_stop_on_user_error<2); if(ret) returnret; mutex_lock(&binder_lock); thread=binder_get_thread(proc); if(thread==NULL){ ret=-ENOMEM; gotoerr; } switch(cmd){ caseBINDER_WRITE_READ:{ structbinder_write_readbwr; if(size!=sizeof(structbinder_write_read)){ ret=-EINVAL; gotoerr; } if(copy_from_user(&bwr,ubuf,sizeof(bwr))){ ret=-EFAULT; gotoerr; } if(binder_debug_mask&BINDER_DEBUG_READ_WRITE) printk(KERN_INFO"binder:%d:%dwrite%ldat%08lx,read%ldat%08lx\n", proc->pid,thread->pid,bwr.write_size,bwr.write_buffer,bwr.read_size,bwr.read_buffer); if(bwr.write_size>0){ ret=binder_thread_write(proc,thread,(void__user*)bwr.write_buffer,bwr.write_size,&bwr.write_consumed); if(ret<0){ bwr.read_consumed=0; if(copy_to_user(ubuf,&bwr,sizeof(bwr))) ret=-EFAULT; gotoerr; } } if(bwr.read_size>0){ ret=binder_thread_read(proc,thread,(void__user*)bwr.read_buffer,bwr.read_size,&bwr.read_consumed,filp->f_flags&O_NONBLOCK); if(!list_empty(&proc->todo)) wake_up_interruptible(&proc->wait); if(ret<0){ if(copy_to_user(ubuf,&bwr,sizeof(bwr))) ret=-EFAULT; gotoerr; } } if(binder_debug_mask&BINDER_DEBUG_READ_WRITE) printk(KERN_INFO"binder:%d:%dwrote%ldof%ld,readreturn%ldof%ld\n", proc->pid,thread->pid,bwr.write_consumed,bwr.write_size,bwr.read_consumed,bwr.read_size); if(copy_to_user(ubuf,&bwr,sizeof(bwr))){ ret=-EFAULT; gotoerr; } break; } ...... } ret=0; err: ...... returnret; } 函数首先是将用户传进来的参数拷贝到本地变量struct binder_write_read bwr中去。这里bwr.write_size > 0为true,因此,进入到binder_thread_write函数中,我们只关注BC_TRANSACTION部分的逻辑: binder_thread_write(structbinder_proc*proc,structbinder_thread*thread, void__user*buffer,intsize,signedlong*consumed) { uint32_tcmd; void__user*ptr=buffer+*consumed; void__user*end=buffer+size; while(ptr<end&&thread->return_error==BR_OK){ if(get_user(cmd,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); if(_IOC_NR(cmd)<ARRAY_SIZE(binder_stats.bc)){ binder_stats.bc[_IOC_NR(cmd)]++; proc->stats.bc[_IOC_NR(cmd)]++; thread->stats.bc[_IOC_NR(cmd)]++; } switch(cmd){ ..... caseBC_TRANSACTION: caseBC_REPLY:{ structbinder_transaction_datatr; if(copy_from_user(&tr,ptr,sizeof(tr))) return-EFAULT; ptr+=sizeof(tr); binder_transaction(proc,thread,&tr,cmd==BC_REPLY); break; } ...... } *consumed=ptr-buffer; } return0; } 首先将用户传进来的transact参数拷贝在本地变量struct binder_transaction_data tr中去,接着调用binder_transaction函数进一步处理,这里我们忽略掉无关代码: staticvoid binder_transaction(structbinder_proc*proc,structbinder_thread*thread, structbinder_transaction_data*tr,intreply) { structbinder_transaction*t; structbinder_work*tcomplete; size_t*offp,*off_end; structbinder_proc*target_proc; structbinder_thread*target_thread=NULL; structbinder_node*target_node=NULL; structlist_head*target_list; wait_queue_head_t*target_wait; structbinder_transaction*in_reply_to=NULL; structbinder_transaction_log_entry*e; uint32_treturn_error; ...... if(reply){ ...... }else{ if(tr->target.handle){ ...... }else{ target_node=binder_context_mgr_node; if(target_node==NULL){ return_error=BR_DEAD_REPLY; gotoerr_no_context_mgr_node; } } ...... target_proc=target_node->proc; if(target_proc==NULL){ return_error=BR_DEAD_REPLY; gotoerr_dead_binder; } ...... } if(target_thread){ ...... }else{ target_list=&target_proc->todo; target_wait=&target_proc->wait; } ...... /*TODO:reuseincomingtransactionforreply*/ t=kzalloc(sizeof(*t),GFP_KERNEL); if(t==NULL){ return_error=BR_FAILED_REPLY; gotoerr_alloc_t_failed; } ...... tcomplete=kzalloc(sizeof(*tcomplete),GFP_KERNEL); if(tcomplete==NULL){ return_error=BR_FAILED_REPLY; gotoerr_alloc_tcomplete_failed; } ...... if(!reply&&!(tr->flags&TF_ONE_WAY)) t->from=thread; else t->from=NULL; t->sender_euid=proc->tsk->cred->euid; t->to_proc=target_proc; t->to_thread=target_thread; t->code=tr->code; t->flags=tr->flags; t->priority=task_nice(current); t->buffer=binder_alloc_buf(target_proc,tr->data_size, tr->offsets_size,!reply&&(t->flags&TF_ONE_WAY)); if(t->buffer==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_alloc_buf_failed; } t->buffer->allow_user_free=0; t->buffer->debug_id=t->debug_id; t->buffer->transaction=t; t->buffer->target_node=target_node; if(target_node) binder_inc_node(target_node,1,0,NULL); offp=(size_t*)(t->buffer->data+ALIGN(tr->data_size,sizeof(void*))); if(copy_from_user(t->buffer->data,tr->data.ptr.buffer,tr->data_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } if(copy_from_user(offp,tr->data.ptr.offsets,tr->offsets_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } ...... off_end=(void*)offp+tr->offsets_size; for(;offp<off_end;offp++){ structflat_binder_object*fp; ...... fp=(structflat_binder_object*)(t->buffer->data+*offp); switch(fp->type){ caseBINDER_TYPE_BINDER: caseBINDER_TYPE_WEAK_BINDER:{ structbinder_ref*ref; structbinder_node*node=binder_get_node(proc,fp->binder); if(node==NULL){ node=binder_new_node(proc,fp->binder,fp->cookie); if(node==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_new_node_failed; } node->min_priority=fp->flags&FLAT_BINDER_FLAG_PRIORITY_MASK; node->accept_fds=!!(fp->flags&FLAT_BINDER_FLAG_ACCEPTS_FDS); } if(fp->cookie!=node->cookie){ ...... gotoerr_binder_get_ref_for_node_failed; } ref=binder_get_ref_for_node(target_proc,node); if(ref==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_get_ref_for_node_failed; } if(fp->type==BINDER_TYPE_BINDER) fp->type=BINDER_TYPE_HANDLE; else fp->type=BINDER_TYPE_WEAK_HANDLE; fp->handle=ref->desc; binder_inc_ref(ref,fp->type==BINDER_TYPE_HANDLE,&thread->todo); ...... }break; ...... } } if(reply){ ...... }elseif(!(t->flags&TF_ONE_WAY)){ BUG_ON(t->buffer->async_transaction!=0); t->need_reply=1; t->from_parent=thread->transaction_stack; thread->transaction_stack=t; }else{ ...... } t->work.type=BINDER_WORK_TRANSACTION; list_add_tail(&t->work.entry,target_list); tcomplete->type=BINDER_WORK_TRANSACTION_COMPLETE; list_add_tail(&tcomplete->entry,&thread->todo); if(target_wait) wake_up_interruptible(target_wait); return; ...... } 注意,这里传进来的参数reply为0,tr->target.handle也为0。因此,target_proc、target_thread、target_node、target_list和target_wait的值分别为: target_node=binder_context_mgr_node; target_proc=target_node->proc; target_list=&target_proc->todo; target_wait=&target_proc->wait; 接着,分配了一个待处理事务t和一个待完成工作项tcomplete,并执行初始化工作: /*TODO:reuseincomingtransactionforreply*/ t=kzalloc(sizeof(*t),GFP_KERNEL); if(t==NULL){ return_error=BR_FAILED_REPLY; gotoerr_alloc_t_failed; } ...... tcomplete=kzalloc(sizeof(*tcomplete),GFP_KERNEL); if(tcomplete==NULL){ return_error=BR_FAILED_REPLY; gotoerr_alloc_tcomplete_failed; } ...... if(!reply&&!(tr->flags&TF_ONE_WAY)) t->from=thread; else t->from=NULL; t->sender_euid=proc->tsk->cred->euid; t->to_proc=target_proc; t->to_thread=target_thread; t->code=tr->code; t->flags=tr->flags; t->priority=task_nice(current); t->buffer=binder_alloc_buf(target_proc,tr->data_size, tr->offsets_size,!reply&&(t->flags&TF_ONE_WAY)); if(t->buffer==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_alloc_buf_failed; } t->buffer->allow_user_free=0; t->buffer->debug_id=t->debug_id; t->buffer->transaction=t; t->buffer->target_node=target_node; if(target_node) binder_inc_node(target_node,1,0,NULL); offp=(size_t*)(t->buffer->data+ALIGN(tr->data_size,sizeof(void*))); if(copy_from_user(t->buffer->data,tr->data.ptr.buffer,tr->data_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } if(copy_from_user(offp,tr->data.ptr.offsets,tr->offsets_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } 注意,这里的事务t是要交给target_proc处理的,在这个场景之下,就是Service Manager了。因此,下面的语句: t->buffer=binder_alloc_buf(target_proc,tr->data_size, tr->offsets_size,!reply&&(t->flags&TF_ONE_WAY)); 就是在Service Manager的进程空间中分配一块内存来保存用户传进入的参数了: if(copy_from_user(t->buffer->data,tr->data.ptr.buffer,tr->data_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } if(copy_from_user(offp,tr->data.ptr.offsets,tr->offsets_size)){ ...... return_error=BR_FAILED_REPLY; gotoerr_copy_data_failed; } 由于现在target_node要被使用了,增加它的引用计数: if(target_node) binder_inc_node(target_node,1,0,NULL); 接下去的for循环,就是用来处理传输数据中的Binder对象了。在我们的场景中,有一个类型为BINDER_TYPE_BINDER的Binder实体MediaPlayerService: switch(fp->type){ caseBINDER_TYPE_BINDER: caseBINDER_TYPE_WEAK_BINDER:{ structbinder_ref*ref; structbinder_node*node=binder_get_node(proc,fp->binder); if(node==NULL){ node=binder_new_node(proc,fp->binder,fp->cookie); if(node==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_new_node_failed; } node->min_priority=fp->flags&FLAT_BINDER_FLAG_PRIORITY_MASK; node->accept_fds=!!(fp->flags&FLAT_BINDER_FLAG_ACCEPTS_FDS); } if(fp->cookie!=node->cookie){ ...... gotoerr_binder_get_ref_for_node_failed; } ref=binder_get_ref_for_node(target_proc,node); if(ref==NULL){ return_error=BR_FAILED_REPLY; gotoerr_binder_get_ref_for_node_failed; } if(fp->type==BINDER_TYPE_BINDER) fp->type=BINDER_TYPE_HANDLE; else fp->type=BINDER_TYPE_WEAK_HANDLE; fp->handle=ref->desc; binder_inc_ref(ref,fp->type==BINDER_TYPE_HANDLE,&thread->todo); ...... }break; 由于是第一次在Binder驱动程序中传输这个MediaPlayerService,调用binder_get_node函数查询这个Binder实体时,会返回空,于是binder_new_node在proc中新建一个,下次就可以直接使用了。 现在,由于要把这个Binder实体MediaPlayerService交给target_proc,也就是Service Manager来管理,也就是说Service Manager要引用这个MediaPlayerService了,于是通过binder_get_ref_for_node为MediaPlayerService创建一个引用,并且通过binder_inc_ref来增加这个引用计数,防止这个引用还在使用过程当中就被销毁。注意,到了这里的时候,t->buffer中的flat_binder_obj的type已经改为BINDER_TYPE_HANDLE,handle已经改为ref->desc,跟原来不一样了,因为这个flat_binder_obj是最终是要传给Service Manager的,而Service Manager只能够通过句柄值来引用这个Binder实体。 最后,把待处理事务加入到target_list列表中去: list_add_tail(&t->work.entry,target_list); 并且把待完成工作项加入到本线程的todo等待执行列表中去: list_add_tail(&tcomplete->entry,&thread->todo); 现在目标进程有事情可做了,于是唤醒它: if(target_wait) wake_up_interruptible(target_wait); 这里就是要唤醒Service Manager进程了。回忆一下前面浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路这篇文章,此时, Service Manager正在binder_thread_read函数中调用wait_event_interruptible进入休眠状态。 这里我们先忽略一下Service Manager被唤醒之后的场景,继续MedaPlayerService的启动过程,然后再回来。 回到binder_ioctl函数,bwr.read_size > 0为true,于是进入binder_thread_read函数: staticint binder_thread_read(structbinder_proc*proc,structbinder_thread*thread, void__user*buffer,intsize,signedlong*consumed,intnon_block) { void__user*ptr=buffer+*consumed; void__user*end=buffer+size; intret=0; intwait_for_proc_work; if(*consumed==0){ if(put_user(BR_NOOP,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); } retry: wait_for_proc_work=thread->transaction_stack==NULL&&list_empty(&thread->todo); ....... if(wait_for_proc_work){ ....... }else{ if(non_block){ if(!binder_has_thread_work(thread)) ret=-EAGAIN; }else ret=wait_event_interruptible(thread->wait,binder_has_thread_work(thread)); } ...... while(1){ uint32_tcmd; structbinder_transaction_datatr; structbinder_work*w; structbinder_transaction*t=NULL; if(!list_empty(&thread->todo)) w=list_first_entry(&thread->todo,structbinder_work,entry); elseif(!list_empty(&proc->todo)&&wait_for_proc_work) w=list_first_entry(&proc->todo,structbinder_work,entry); else{ if(ptr-buffer==4&&!(thread->looper&BINDER_LOOPER_STATE_NEED_RETURN))/*nodataadded*/ gotoretry; break; } if(end-ptr<sizeof(tr)+4) break; switch(w->type){ ...... caseBINDER_WORK_TRANSACTION_COMPLETE:{ cmd=BR_TRANSACTION_COMPLETE; if(put_user(cmd,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); binder_stat_br(proc,thread,cmd); if(binder_debug_mask&BINDER_DEBUG_TRANSACTION_COMPLETE) printk(KERN_INFO"binder:%d:%dBR_TRANSACTION_COMPLETE\n", proc->pid,thread->pid); list_del(&w->entry); kfree(w); binder_stats.obj_deleted[BINDER_STAT_TRANSACTION_COMPLETE]++; }break; ...... } if(!t) continue; ...... } done: ...... return0; } 这里,thread->transaction_stack和thread->todo均不为空,于是wait_for_proc_work为false,由于binder_has_thread_work的时候,返回true,这里因为thread->todo不为空,因此,线程虽然调用了wait_event_interruptible,但是不会睡眠,于是继续往下执行。 由于thread->todo不为空,执行下列语句: if(!list_empty(&thread->todo)) w=list_first_entry(&thread->todo,structbinder_work,entry); w->type为BINDER_WORK_TRANSACTION_COMPLETE,这是在上面的binder_transaction函数设置的,于是执行: switch(w->type){ ...... caseBINDER_WORK_TRANSACTION_COMPLETE:{ cmd=BR_TRANSACTION_COMPLETE; if(put_user(cmd,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); ...... list_del(&w->entry); kfree(w); }break; ...... } 这里就将w从thread->todo删除了。由于这里t为空,重新执行while循环,这时由于已经没有事情可做了,最后就返回到binder_ioctl函数中。注间,这里一共往用户传进来的缓冲区buffer写入了两个整数,分别是BR_NOOP和BR_TRANSACTION_COMPLETE。 binder_ioctl函数返回到用户空间之前,把数据消耗情况拷贝回用户空间中: if(copy_to_user(ubuf,&bwr,sizeof(bwr))){ ret=-EFAULT; gotoerr; } 最后返回到IPCThreadState::talkWithDriver函数中,执行下面语句: if(err>=NO_ERROR){ if(bwr.write_consumed>0){ if(bwr.write_consumed<(ssize_t)mOut.dataSize()) mOut.remove(0,bwr.write_consumed); else mOut.setDataSize(0); } if(bwr.read_consumed>0){ <PREclass=cppname="code">mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0);</PRE>}......returnNO_ERROR;} 首先是把mOut的数据清空: mOut.setDataSize(0); 然后设置已经读取的内容的大小: mIn.setDataSize(bwr.read_consumed); mIn.setDataPosition(0); 然后返回到IPCThreadState::waitForResponse函数中。在IPCThreadState::waitForResponse函数,先是从mIn读出一个整数,这个便是BR_NOOP了,这是一个空操作,什么也不做。然后继续进入IPCThreadState::talkWithDriver函数中。 这时候,下面语句执行后: constboolneedRead=mIn.dataPosition()>=mIn.dataSize(); needRead为false,因为在mIn中,尚有一个整数BR_TRANSACTION_COMPLETE未读出。 这时候,下面语句执行后: constsize_toutAvail=(!doReceive||needRead)?mOut.dataSize():0; outAvail等于0。因此,最后bwr.write_size和bwr.read_size均为0,IPCThreadState::talkWithDriver函数什么也不做,直接返回到IPCThreadState::waitForResponse函数中。在IPCThreadState::waitForResponse函数,又继续从mIn读出一个整数,这个便是BR_TRANSACTION_COMPLETE: switch(cmd){ caseBR_TRANSACTION_COMPLETE: if(!reply&&!acquireResult)gotofinish; break; ...... } reply不为NULL,因此,IPCThreadState::waitForResponse的循环没有结束,继续执行,又进入到IPCThreadState::talkWithDrive中。 这次,needRead就为true了,而outAvail仍为0,所以bwr.read_size不为0,bwr.write_size为0。于是通过: ioctl(mProcess->mDriverFD,BINDER_WRITE_READ,&bwr) 进入到Binder驱动程序中的binder_ioctl函数中。由于bwr.write_size为0,bwr.read_size不为0,这次直接就进入到binder_thread_read函数中。这时候,thread->transaction_stack不等于0,但是thread->todo为空,于是线程就通过: wait_event_interruptible(thread->wait,binder_has_thread_work(thread)); 进入睡眠状态,等待Service Manager来唤醒了。 现在,我们可以回到Service Manager被唤醒的过程了。我们接着前面浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路这篇文章的最后,继续描述。此时, Service Manager正在binder_thread_read函数中调用wait_event_interruptible_exclusive进入休眠状态。上面被MediaPlayerService启动后进程唤醒后,继续执行binder_thread_read函数: staticint binder_thread_read(structbinder_proc*proc,structbinder_thread*thread, void__user*buffer,intsize,signedlong*consumed,intnon_block) { void__user*ptr=buffer+*consumed; void__user*end=buffer+size; intret=0; intwait_for_proc_work; if(*consumed==0){ if(put_user(BR_NOOP,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); } retry: wait_for_proc_work=thread->transaction_stack==NULL&&list_empty(&thread->todo); ...... if(wait_for_proc_work){ ...... if(non_block){ if(!binder_has_proc_work(proc,thread)) ret=-EAGAIN; }else ret=wait_event_interruptible_exclusive(proc->wait,binder_has_proc_work(proc,thread)); }else{ ...... } ...... while(1){ uint32_tcmd; structbinder_transaction_datatr; structbinder_work*w; structbinder_transaction*t=NULL; if(!list_empty(&thread->todo)) w=list_first_entry(&thread->todo,structbinder_work,entry); elseif(!list_empty(&proc->todo)&&wait_for_proc_work) w=list_first_entry(&proc->todo,structbinder_work,entry); else{ if(ptr-buffer==4&&!(thread->looper&BINDER_LOOPER_STATE_NEED_RETURN))/*nodataadded*/ gotoretry; break; } if(end-ptr<sizeof(tr)+4) break; switch(w->type){ caseBINDER_WORK_TRANSACTION:{ t=container_of(w,structbinder_transaction,work); }break; ...... } if(!t) continue; BUG_ON(t->buffer==NULL); if(t->buffer->target_node){ structbinder_node*target_node=t->buffer->target_node; tr.target.ptr=target_node->ptr; tr.cookie=target_node->cookie; ...... cmd=BR_TRANSACTION; }else{ ...... } tr.code=t->code; tr.flags=t->flags; tr.sender_euid=t->sender_euid; if(t->from){ structtask_struct*sender=t->from->proc->tsk; tr.sender_pid=task_tgid_nr_ns(sender,current->nsproxy->pid_ns); }else{ tr.sender_pid=0; } tr.data_size=t->buffer->data_size; tr.offsets_size=t->buffer->offsets_size; tr.data.ptr.buffer=(void*)t->buffer->data+proc->user_buffer_offset; tr.data.ptr.offsets=tr.data.ptr.buffer+ALIGN(t->buffer->data_size,sizeof(void*)); if(put_user(cmd,(uint32_t__user*)ptr)) return-EFAULT; ptr+=sizeof(uint32_t); if(copy_to_user(ptr,&tr,sizeof(tr))) return-EFAULT; ptr+=sizeof(tr); ...... list_del(&t->work.entry); t->buffer->allow_user_free=1; if(cmd==BR_TRANSACTION&&!(t->flags&TF_ONE_WAY)){ t->to_parent=thread->transaction_stack; t->to_thread=thread; thread->transaction_stack=t; }else{ t->buffer->transaction=NULL; kfree(t); binder_stats.obj_deleted[BINDER_STAT_TRANSACTION]++; } break; } done: ...... return0; } 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/964539,如需转载请自行联系原作者