block-coroutine-wrapper

QEMU 块层(见 block/)的许多函数只能在协程上下文调用, 通常以 coroutine_fn 标记。但有时需要从非协程上下文调用它们: 先启动协程,在其中运行目标函数,再通过 BDRV_POLL_WHILE() 循环等待结束。 运行协程需要一个只有 void 参数的函数。 因此,为每个需要非协程接口的 coroutine_fn 函数,都要定义结构体封装参数, 另写函数解包并调用原函数,最后定义与原函数参数列表相同的接口函数, 负责打包参数、创建并运行协程,以及在 BDRV_POLL_WHILE() 中等待。 手写这些封装很繁琐,因此提供脚本自动生成。

用法

假设已定义 coroutine_fn 函数 bdrv_co_foo(<some args>), 需要名为 bdrv_foo(<same args>) 的非协程接口,可以用脚本生成。 触发生成的方法如下:

  1. 在某处(例如 block/coroutines.h)提供带 co_wrapper 标记的 bdrv_foo 声明:

int co_wrapper bdrv_foo(<some args>);
  1. 将声明传给 block-coroutine-wrapper 脚本。 在 block/meson.build 的 block_gen_c 目标定义中, 将含声明的 .h 或 .c 文件加入 input: files(...) 列表。

这样就完成了。构建期间,协程封装会生成到 <BUILD_DIR>/block/block-gen.c。