源码分析 ---------openHarmony IPC数据传输情景分析 原创 精华
源码分析 ---------openHarmony IPC数据传输情景分析
1.前情概览
我们在前片博客中讲述了 proxy - stub 架构的一般编程范式,这篇文章关注驱动自身的数据传输,做一次完整的数据分析。由于IPC通信流程比较复杂,我们先开启上帝视角,将一些数据结构和数据流向直接阐述出来,然后再结合源码调用流查看是否具体是这样的。
2.数据结构简述
2.1messageParcel
messageParcel 用户态数据,可以写入一般类型,也可以写入iremoteObject。为什么要区分这两种类型,这里先卖一个关子。
2.2 flat_binder_object
这是内核描述iremoteObject对象信息的结构体。当调用 object->Marshalling(*this)的时候将转化为flat_binder_object,然后写入到messageparcel对象中。同理还有一个UnMarshalling方法将parcel中的flat_binder_object读出来,然后转化为iremoteObject对象
2.3 binder_transaction_data
这个数据不仅包含了flat_binder_object中的纯数据,也包含的cmdID以及发送者的其他信息。
2.4 binder_write_read
驱动真正读写的数据,也就是binder_transaction_data 会转化为binder_write_read交给驱动真正的读写。
2.5 binder_ref
binder_ref是描述Binder引用的结构体。
2.6 binder_proc
2.7 binder_node
binder_node是描述Binder实体的结构体。
3.情景分析
3.1 数据流向
其实结合上文,一次的数据发送。其实就是 messageParcel ->flat_binder_object -> binder_transaction_data -> binder_write_read。上文中我们说到普通数据和iremoteObjiect有区别,那区别是啥,就是发送的数据里面包含iremoteObJiect,驱动程序就会在全局哈希表binder_procs中注册一个binder_proc。那普通数据和iremote数据是如何区分呢?答案是他有两个指针一个指向普通的数据,另一个指向iremoteObject。也就是binder_transaction_data的buffer指针和offsets指针。那binder驱动在这个数据发送的过程中做了什么呢?
3.2 驱动事件循环
binder_ref-> binder_proc->binder_node
对于发送者来说,要知道发送的数据需要传输给谁,他自身持有一个服务进程的binder_ref,通过binder_ref找到对应的binder_proc,然后通过binder_proc找到对应的binder_node(一个进程可以有多个binder_node,即可以有多个服务)。那binder_write_read中获取的数据也就会添加到宿主进程binder_proc的todo链表中。
源码调用图解
中划线
client和stub的交互过程就是 client - > stub ->client 这样看起来就像自身进程调用自己的方法一样。上图中ipcObjectStub -> OnRemoteRequest()就会向binder驱动放松数据,这也是为什么继承的子类需要重写OnRemoteRequest方法。
这里就是大概ipc调用的过程,对驱动自身的阐述比较浅薄,驱动中的多线程模型还有自身数据结构的复杂性并没有阐述。如果有机会研究后,再讲讲dsoftbus驱动和binder驱动的不同和相似之处,讲讲iremoteObJect是如何适配这两种不同驱动模型的。
赞,情景中各个环节讲的很清楚,结构体的注释也很详细,感谢分享
666
十分清晰,感谢老师分享
6666