android系统源码分析——binder基础数据结构

fen在Binder驱动程序中有两种类型的数据结构,其中一种是在内部使用的,另一种是在内部和外部均会使用的

1.binder_work用来描述待处理的工作项。

2.binder_node用来描述一个Binder实体对象。

3.binder_ref_death用来描述一个Service组件的死亡接收通知。

4.binder_ref用来描述一个Binder引用对象。

5.binder_buffer用来描述一个内核缓冲区,它是用来在进程间传输数据的。

6.binder_proc用来描述一个正在使用Binder进程间通信机制的过程。

7.binder_thread用来描述Binder线程池中的一个线程,其中成员变量proc指向宿主进程。

8.binder_transaction用来描述进程间通信过程,这个过程又称为一个事务。

9.binder_ptr_cookie用来描述一个Binder实体对象或一个Service组件的死亡接收通知。

10.binder_transaction_data用来描述进程间通信过程中所传输的数据。

11.flat_binder_object描述一个Binder实体对象,一个Binder引用对象,一个文件描述符,他们是通过成员变量type来加以区别的。


一. binder_work待处理的工作项。

struct binder_work {
struct list_head entry;//用来将该结构体嵌入到一个宿主进程。
enum {
BINDER_WORK_TRANSACTION = 1,
BINDER_WORK_TRANSACTION_COMPLETE,
BINDER_WORK_NODE,
        //Binder驱动检测到Service组件死亡时,找到Binder实体对象中的refs,
        //找到引用它的client进程和Client进程主动注册死亡通知发现Service组件已死亡两种情况
        BINDER_WORK_DEAD_BINDER,
//Client进程注销死亡通知时,相应的Service组件已死亡,
        //binder驱动找到之前注册的binder_ref_death结构体,并修改它work修改为此,
BINDER_WORK_DEAD_BINDER_AND_CLEAR,
//Client进程注销一个死亡通知,相应的Service组件没有死亡,Binder驱动程序
//会找到之前注册的,一个binder_ref_death结构体,并且将它的work修改为此,
//然后将该结构体封装成一个工作项添加到Client进程的todo队列中 
BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
} type;//描述工作项的类型,根据type取值,Binder驱动程序可以
      //判断出一个binder_work结构图嵌入到什么类型的宿主进程。
};

二.binder_node用来描述一个Binder实体对象。 Service中的Binder在内核中的代表


struct binder_node {
int debug_id;
//引用计数发生变化时 BINDER_WORK_NODE,并且将它添加到响应进程的todo队列中
struct binder_work work;
union {
struct rb_node rb_node;
struct hlist_node dead_node;
};
struct binder_proc *proc;//指向service进程
struct hlist_head refs;//所有的Client的binder引用binder_ref->node
int internal_strong_refs;
int local_weak_refs;
int local_strong_refs;
void __user *ptr;//指向Service组件内部的一个引用计数weakref_impl弱引用计数
void __user *cookie;//指向Service组件的地址
unsigned has_strong_ref:1;//请求Service组件时 1  结束 0
unsigned pending_strong_ref:1;// 请求的时候为1,service增加后为0
unsigned has_weak_ref:1;//请求Service组件时 1  结束 0
unsigned pending_weak_ref:1;
unsigned has_async_transaction:1;//每一个事务都关联一个binder实体对象
//是否接收含有文件描述符的进程间通信数据   防止源进程在目标进程中打开
unsigned accept_fds:1;
unsigned min_priority:8;//线程优先级
struct list_head async_todo;//异步事务队列
};

三.binder_ref_death用来描述一个Service组件的死亡接收通知
Service组件,在驱动中的binder_node,binder_ref都维护引用计数,描述Client组件的死亡通知在驱动中的代表,

struct binder_ref_death {
struct binder_work work;//进程间通信根据Client和Server的状态设置该值  
void __user *cookie;//保存Client负责接收死亡通知对象的地址
};

四.binder_ref用来描述一个Binder引用对象。

Binder驱动程序决定向客户端进程发送一个Service组件死亡通知时。会将binder_ref_death结构体封装成一个工作项。加到Client进程的todo队列中 ,Client进程在处理这个工作项,会通过binder_ref_death结构体成员变量的work来区是哪一种情况,见第一个结构体中的枚举值描述一个Binder引用对象 Client进程中的Binder引用在驱动中的代表

struct binder_ref {
/* Lookups needed: */
/*   node + proc => ref (transaction) */
/*   desc + proc => ref (transaction, inc/dec ref) */
/*   node => refs + procs (proc exit) */
int debug_id;
struct rb_node rb_node_desc;//保存进程内部所有的句柄值
struct rb_node rb_node_node;
struct hlist_node node_entry;//hash列表中的节点 对应与binder_node->refs
struct binder_proc *proc;//Binder引用对象的宿主进程
struct binder_node *node;//Binder引用对象所引用的Binder实体对象
uint32_t desc;//在Client进程的用户空间,Binder引用对象是使用一个句柄值来描述的,
             //BInder驱动程序就可以通过该句柄值找到对于的,Binder引用对象即是binder_ref 
int strong;
int weak;
struct binder_ref_death *death;//Client进程注册的死亡通知保存的地方
};

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/u010231625/article/details/51955390
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞