




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析中,我们系统地介绍了Android系统匿名共享内存的实现原理,其中着重介绍了它是如何辅助内存管理系统来有效地管理内存的,在再前面一篇文章Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划中,我们还提到,Android系统匿名共享内存的另外一特点是通过Binder进程间通信机制来实现进程间共享的,本文中,将详细介绍Android系统匿名共享内存是如何使用Binder进程间通信机制来实现进程间共享的。 由于Android系统匿名共享内存在进程间共享的原理涉及到Binder进程间通信机制的相关知识,所以希望读者在继续阅读本文之前,最好对Android系统的Binder进程间通信机制有一定的了解,具体可以参考Android进程间通信(IPC)机制Binder简要介绍和学习计划这篇文章。 在Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划这篇文章中,我们举了一个例子来简要地介绍了Android系统的匿名共享内存机制及其使用方法,在这篇文章中,我们继续以这个实例来说明Android系统的匿名共享内存是如何使用Binder进程间通信机制来实现进程间共享的。为了方便描述,结合前面的Binder进程间通信机制知识,我们通过下面这个序列图来总结这个实例中的匿名共享内存文件的文件描述符在进程间传输的过程: 这里, 我们需要关注的便是虚线框部分了,它在Binder驱动程序中实现了在两个进程中共享同一个打开文件的方法。我们知道,在Linux系统中,文件描述符其实就是一个整数。每一个进程在内核空间都有一个打开文件的数组,这个文件描述符的整数值就是用来索引这个数组的,而且,这个文件描述符只是在本进程内有效,也就是说,在不同的进程中,相同的文件描述符的值,代表的可能是不同的打开文件。因此,在进程间传输文件描述符时,不能简要地把一个文件描述符从一个进程传给另外一个进程,中间必须做一过转换,使得这个文件描述在目标进程中是有效的,并且它和源进程的文件描述符所对应的打开文件是一致的,这样才能保证共享。 在浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路一文中,我们介绍了用来传输的Binder对象的数据结构struct flat_binder_object,它定义在kernel/common/drivers/staging/android/binder.h 文件中:view plain1. /*2. *ThisistheflattenedrepresentationofaBinderobjectfortransfer3. *betweenprocesses.Theoffsetssuppliedaspartofabindertransaction4. *containsoffsetsintothedatawherethesestructuresoccur.TheBinder5. *drivertakescareofre-writingthestructuretypeanddataasitmoves6. *betweenprocesses.7. */8. structflat_binder_object9. /*8bytesforlarge_flat_header.*/10. unsignedlongtype;11. unsignedlongflags;12. 13. /*8bytesofdata.*/14. union15. void*binder;/*localobject*/16. signedlonghandle;/*remoteobject*/17. ;18. 19. /*extradataassociatedwithlocalobject*/20. void*cookie;21. ; 域type是一个枚举类型,它的取值范围是:view plain1. enum2. BINDER_TYPE_BINDER=B_PACK_CHARS(s,b,*,B_TYPE_LARGE),3. BINDER_TYPE_WEAK_BINDER=B_PACK_CHARS(w,b,*,B_TYPE_LARGE),4. BINDER_TYPE_HANDLE=B_PACK_CHARS(s,h,*,B_TYPE_LARGE),5. BINDER_TYPE_WEAK_HANDLE=B_PACK_CHARS(w,h,*,B_TYPE_LARGE),6. BINDER_TYPE_FD=B_PACK_CHARS(f,d,*,B_TYPE_LARGE),7. ; 这里我们要介绍的Binder对象的type便是BINDER_TYPE_FD了,要传输的文件描述符的值保存在handle域中。 在Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析一文中,我们详细介绍了Binder对象在进程间通信传输的完整过程,这里就不再详述了,有兴趣的读都可以回过头去参考一下。这里,我们只关注文件描述符类型的Binder对象在Binder驱动程序中的相关处理逻辑。 文件描述符类型的Binder对象在Binder驱动程序中的相关处理逻辑实现在binder_transact函数,这个函数定义在kernel/common/drivers/staging/android/binder.c文件中:view plain1. staticvoid2. binder_transaction(structbinder_proc*proc,structbinder_thread*thread,3. structbinder_transaction_data*tr,intreply)4. 5. structbinder_transaction*t;6. structbinder_work*tcomplete;7. size_t*offp,*off_end;8. structbinder_proc*target_proc;9. structbinder_thread*target_thread=NULL;10. structbinder_node*target_node=NULL;11. structlist_head*target_list;12. wait_queue_head_t*target_wait;13. structbinder_transaction*in_reply_to=NULL;14. structbinder_transaction_log_entry*e;15. uint32_treturn_error;16. 17. .18. 19. 20. offp=(size_t*)(t-buffer-data+ALIGN(tr-data_size,sizeof(void*);21. 22. .23. 24. off_end=(void*)offp+tr-offsets_size;25. for(;offpbuffer-data+*offp);29. switch(fp-type)30. .31. caseBINDER_TYPE_FD:32. inttarget_fd;33. structfile*file;34. 35. if(reply)36. if(!(in_reply_to-flags&TF_ACCEPT_FDS)37. binder_user_error(binder:%d:%dgotreplywithfd,%ld,buttargetdoesnotallowfdsn,38. proc-pid,thread-pid,fp-handle);39. return_error=BR_FAILED_REPLY;40. gotoerr_fd_not_allowed;41. 42. elseif(!target_node-accept_fds)43. binder_user_error(binder:%d:%dgottransactionwithfd,%ld,buttargetdoesnotallowfdsn,44. proc-pid,thread-pid,fp-handle);45. return_error=BR_FAILED_REPLY;46. gotoerr_fd_not_allowed;47. 48. 49. file=fget(fp-handle);50. if(file=NULL)51. binder_user_error(binder:%d:%dgottransactionwithinvalidfd,%ldn,52. proc-pid,thread-pid,fp-handle);53. return_error=BR_FAILED_REPLY;54. gotoerr_fget_failed;55. 56. target_fd=task_get_unused_fd_flags(target_proc,O_CLOEXEC);57. if(target_fd%dn,fp-handle,target_fd);65. /*TODO:fput?*/66. fp-handle=target_fd;67. break;68. 69. .70. 71. 72. 73. .74. 75. 这里,我们先明确一下在Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划这篇文章中所举的例子获取匿名共享内存文件的文件描述符的场景。匿名共享内存文件是在Server进程创建的,Client通过IMemoryService.getFileDescriptor去获取Server进程所创建的匿名共享内存文件的文件描述符,Server进程在返回这个文件描述符的过程中进入到Binder驱动程序,即这里的binder_transact函数。因此,这里的当前执行binder_transact函数的进程是Server进程,即源进程是Server进程,而目标进程是Client进程,就是这里的target_proc所表示的进程了。 函数binder_transaction处理文件描述符类型的Binder对象就在中间的for循环里面。 首先是获得Binder对象,并保存在本地变量fp中:view plain1. fp=(structflat_binder_object*)(t-buffer-data+*offp); 文件描述符的值就保存在fp-handle中,通过fget函数取回这个文件描述符所对应的打开文件结构:view plain1. file=fget(fp-handle); 这里的file是一个struct file指针,它表示一个打开文件结构。注间,在Linux系统中,打开文件结构struct file是可以在进程间共享的,它与文件描述符不一样。 接着在目标进程中获得一个空闲的文件描述符:view plain1. target_fd=task_get_unused_fd_flags(target_proc,O_CLOEXEC); 现在,在目标进程中,打开文件结构有了,文件描述符也有了,接下来就可以把这个文件描述符和这个打开文件结构关联起来就可以了:view plain1. task_fd_install(target_proc,target_fd,file); 由于这个Binder对象最终是要返回给目标进程的,所以还要修改fp-handle的值,它原来表示的是在源进程中的文件描述符,现在要改成目标进程的文件描述符:view
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 质量安全岗位管理制度
- 质量检验设备管理制度
- 质量记录控制管理制度
- 监理机构卫生管理制度
- 腾讯外包门禁管理制度
- 小公司工具管理制度
- 职工关系调薪管理制度
- 线下销售人员管理制度
- 终端站点星级管理制度
- 工地上消防管理制度
- 北京海淀十一学校2024届英语七年级第二学期期末教学质量检测模拟试题含答案
- 材料力学(山东联盟-中国石油大学(华东))智慧树知到期末考试答案章节答案2024年中国石油大学(华东)
- 2023-2024学年辽宁省沈阳市皇姑区七年级(下)期末数学试卷(含答案)
- 江西省南昌二中心远教育集团九湾学校2023-2024学年八年级下学期期末考试物理试题
- 深入理解Nginx(模块开发与架构解析)
- 酿酒机械与设备智慧树知到期末考试答案章节答案2024年齐鲁工业大学
- 儿童保健门诊规范化建设标准
- 《庖丁解牛》省公开课金奖全国赛课一等奖微课获奖课件
- MOOC 中国文化概论-华南师范大学 中国大学慕课答案
- 初中人教版八年级下册期末物理真题模拟试卷经典套题
- 24春国家开放大学《离散数学》大作业参考答案
评论
0/150
提交评论