# block-coroutine-wrapper

A lot of functions in QEMU block layer (see `block/*`) can only be called in coroutine context. Such functions are normally marked by the coroutine_fn specifier. Still, sometimes we need to call them from non-coroutine context; for this we need to start a coroutine, run the needed function from it and wait for the coroutine to finish in a BDRV_POLL_WHILE() loop. To run a coroutine we need a function with one void* argument. So for each coroutine_fn function which needs a non-coroutine interface, we should define a structure to pack the parameters, define a separate function to unpack the parameters and call the original function and finally define a new interface function with same list of arguments as original one, which will pack the parameters into a struct, create a coroutine, run it and wait in BDRV_POLL_WHILE() loop. It’s boring to create such wrappers by hand, so we have a script to generate them.

## Usage

Assume we have defined the `coroutine_fn` function `bdrv_co_foo(<some args>)` and need a non-coroutine interface for it, called `bdrv_foo(<same args>)`. In this case the script can help. To trigger the generation:

1. You need `bdrv_foo` declaration somewhere (for example, in `block/coroutines.h`) with the `generated_co_wrapper` mark, like this:

    int generated_co_wrapper bdrv_foo(<some args>);

2. You need to feed this declaration to block-coroutine-wrapper script. For this, add the .h (or .c) file with the declaration to the `input: files(...)` list of `block_gen_c` target declaration in `block/meson.build`

You are done. During the build, coroutine wrappers will be generated in `<BUILD_DIR>/block/block-gen.c`.

## Links

1. The script location is `scripts/block-coroutine-wrapper.py`.

2. Generic place for private `generated_co_wrapper` declarations is `block/coroutines.h`, for public declarations: `include/block/block.h`

3. The core API of generated coroutine wrappers is placed in (not generated) `block/block-gen.h`