5.6.7Binder系统_驱动情景分析_transaction_stack机制_REPLY

目录

回顾

简单概述

情景分析

BC_TRANSACTION过程

BC_TRANSACTION过程


回顾

通过前面的学习我们知道,binder通信涉及搭配两个进程,A,B:

A发送一个BC_TRANSACTION消息给驱动,驱动把其转化为BR_TRANSACTIONB转发给B。
B接收到一个类型为BR_TRANSACTIONB的数据,然后发送一个BC_REPLY的消息给驱动,驱动把其转化为BR_REPLY,然后回复给A进程。

简单概述


在前面的分析中,我们没有详细的分析,驱动程序中,如何查找到消息的目的进程。该小节我们进行详细的分析。主要解决以下两个问题即可:
1.发给谁?handle只表明了进程,是发送给进程,还是发送给线程?
2.回复给谁?回复的时候没有了handle表明目的进程,必定在某个地方记录了发送者(即后面要讲解的transaction_stack)

在获取服务的时候,我们获得的handle代表一个进程,但是需要发送的目标可能是某个线程。

如test_client要发送数据给test_sever。
test_sever中存在多个线程(binder_thread),其在binder驱动中,对应一个binder_proc结构体,并且还有一个todo链表。但是binder_thread中也存在一个todo链表。那么问题来了,发送数据的时候,我们是把数据放入binder_proc的todo链表还是放入binder_thread的todo链表呢?

一般来说,test_client会把数据放入到binder_proc的todo链表中,唤醒等待于binder_proc.wait的空闲线程。但是也有特殊情况,对于双向传输,则放在binder_thread.todo中,然后唤醒该线程。那怎么分辨是否为双向传输呢?其也是通过该小节要讲解的transaction_stack机制来判断。

下面我们进行情景分析。
 

情景分析

下面是一个test_client与test_server执行的流程图:

test_client发送一个BC_TRANSACTION,test_server接收到一个BR_TRANSACTION。test_server处理完成之后发送BC_REPLY给test_client,test_client接收到一个BR_REPLY。

根据这四个过程,我们看看transaction_stack是如何其作用的,前面分析过,binder_ioctl最终会调用到binder_transaction()函数,
 

static void binder_transaction(struct binder_proc *proc,struct binder_thread *thread,struct binder_transaction_data *tr, int reply,binder_size_t extra_buffers_size)
	if (reply) {
		......
	} else {
		struct binder_ref *ref;
		/*根据tr->target.handle获得一个struct binder_ref *ref*/
		ref = binder_get_ref_olocked(proc, tr->target.handle,true);
		/*根据ref获得struct binder_node *target_node,即目的节点*/
		target_node = binder_get_node_refs_for_txn(ref->node, &target_proc,&return_error);
		......
		......

下面是一个详细的框图,我们围绕该框图进行讲解:

BC_TRANSACTION过程

1.在一开始的时候,test_client与test_server是非双向传输的,所以数据将放在test_server的binder_proc.todo的链表中,唤醒test_server.binder_proc.wait上等待到得线程

static void binder_transaction(struct binder_proc *proc,struct binder_thread *thread,struct binder_transaction_data *tr, int reply,binder_size_t extra_buffers_size)
	/*发送之后还想得到回复*/
	} else if (!(t->flags & TF_ONE_WAY)) {
		/*一个链表的操作,入栈。t中包含了甚多信息,如发送给谁,从哪里开始发送等等*/
		t->from_parent = thread->transaction_stack;
	/*进程在没有创建线线程的时候,也存在一个主线程*/
	binder_enqueue_work(proc, tcomplete, &thread->todo);

2.test_client中的binder_thread存在.transaction_stack指向一个传输结构。

BC_TRANSACTION过程

test_server接收到BR_TRANSACTION之后:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值