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進程註冊的死亡通知保存的地方
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章