android (4)
2011-7-15 20:16:42
refs_by_node 这个节点就是 node_ref 组成的红黑树
节点的值就是 binder_node 的地址组成
前一节所说
if (target == 0 && binder_context_mgr_node &&
(cmd == BC_INCREFS || cmd == BC_ACQUIRE)) {
ref = binder_get_ref_for_node(proc,
binder_context_mgr_node);
if (ref->desc != target) {
binder_user_error("binder: %d:"
"%d tried to acquire "
"reference to desc 0, "
"got %d instead\n",
proc->pid, thread->pid,
ref->desc);
}
} else
ref = binder_get_ref(proc, target);
if (ref == NULL) {
binder_user_error("binder: %d:%d refcou"
"nt change on invalid ref %d\n",
proc->pid, thread->pid, target);
break;
}
解析了命令 解析了目标
如果满足了target 为0,且有binder_node 存在
命令为增加引用或查询
则调用 binder_get_ref_for_node 找出 binder_context_mgr_node 的引用关系
binder_node 都在这呢 refs_by_node
binder_ref 的排序规则就是按binder_node的地址来的
找到了就返回
如果找不到对应的改怎么办?
说明作为参数传入的binder_node 没有加入到这个ref 链表中
那么就需要创建一个binder_ref结构
插入到2棵红黑树中,一个以binder_node 的地址排序
一个以desc 排序
那么也就是说除了通过node来查找引用外 还可以使用描述来查找引用
最终这个binder_ref还需要插入到node的ref链表中
如果引用的描述和目标不符合,还是会报错
如果命令是 BC_INCREFS
通过binder_inc_node 增加了ref结构和node的弱引用
如果是 BC_ACQUIRE
就增加强引用
BC_RELEASE
就是降低强引用
BC_DECREFS
就是减少弱引用
如果命令是 BC_INCREFS_DONE 或 BC_ACQUIRE_DONE
binder_node 指针是从用户层传入的,同时传入的还有cookie
通过指针找到这个binder_node之后还需要通过cookie进行验证
再验证 pending 状态
binder_node 有这样一个字段 struct binder_work {
struct list_head entry;
enum {
BINDER_WORK_TRANSACTION = 1,
BINDER_WORK_TRANSACTION_COMPLETE,
BINDER_WORK_NODE,
BINDER_WORK_DEAD_BINDER,
BINDER_WORK_DEAD_BINDER_AND_CLEAR,
BINDER_WORK_CLEAR_DEATH_NOTIFICATION,
} type;
};
binder_dec_node 减少引用