目录
消息循环Message Loop
Fuchsia应用程序通过libasync-loop创建和使用消息循环Message Loop, 应用程序必须拥有Message Loop才能正常工作,比如跨进程IPC调用. 为了描述更具体, 本文以下面这个main函数说明Message Loop的运行原理.
int main(int argc, const char** argv) {
async::Loop loop(&kAsyncLoopConfigAttachToThread);
......
loop.Run();
return 0;
}
Message Loop工作原理
![](https://i-blog.csdnimg.cn/blog_migrate/94a01a82ccbb67459ffbc7a14f769ab9.jpeg)
Message Loop主要分2个库
- libasync-loop (fuchsia/zircon/system/ulib/async-loop) 包装和实现了消息循环Loop类
- libasync (fuchsia/zircon/system/ulib/async) 包装和实现了异步等待Wait类
![](https://i-blog.csdnimg.cn/blog_migrate/68d2c1cb22663d48d1a87f6ae26f40cf.jpeg)
Message Loop的工作过程包括4个主要步骤,详细的时序分析参考上图
- Loop类初始化过程即main函数的
async::Loop loop(&kAsyncLoopConfigAttachToThread);
- 主线程消息循环过程即main函数的
loop.Run();
- 应用程序通过某些类创建Wait实例注册需要等待的对象以及回调通知函数
- 应用程序通过某些包装类调用了Wait的Begin开始异步等待对象上出现期望的SIGNAL并触发回调通知 (比如FIDL IPC过程中通过MessageReader调用Bind方法调用async_begin_wait等待channel对象有数据可读,然后回调MessageReader::CallHandler来处理)
Message Loop在IPC中的作用
![](https://i-blog.csdnimg.cn/blog_migrate/681d7d50dc26369da95358f1a89ed870.jpeg)
- 通过zx_port_create创建可以等待的port对象,通过zx_channel_create创建跨进程通信的channel
- 通过zx_object_wait_async指定等待哪个handle(通常就是创建的channel),在哪个port上等待以及等待成功后packet中的key(用于指定回调函数handler)
- 创建Message Loop通过zx_port_wait block在port上等待handle上发生signal(比如channel上有数据可以read)
- 另外一个进程通过zx_channel_write发送数据
- zx_port_wait返回packets数据,通过packet.key可以找到对应的回调函数handler并通过zx_channel_read读取channel上的数据