| 1 | ======================= |
| 2 | block-coroutine-wrapper |
| 3 | ======================= |
| 4 | |
| 5 | A lot of functions in QEMU block layer (see ``block/*``) can only be |
| 6 | called in coroutine context. Such functions are normally marked by the |
| 7 | coroutine_fn specifier. Still, sometimes we need to call them from |
| 8 | non-coroutine context; for this we need to start a coroutine, run the |
| 9 | needed function from it and wait for the coroutine to finish in a |
| 10 | BDRV_POLL_WHILE() loop. To run a coroutine we need a function with one |
| 11 | void* argument. So for each coroutine_fn function which needs a |
| 12 | non-coroutine interface, we should define a structure to pack the |
| 13 | parameters, define a separate function to unpack the parameters and |
| 14 | call the original function and finally define a new interface function |
| 15 | with same list of arguments as original one, which will pack the |
| 16 | parameters into a struct, create a coroutine, run it and wait in |
| 17 | BDRV_POLL_WHILE() loop. It's boring to create such wrappers by hand, |
| 18 | so we have a script to generate them. |
| 19 | |
| 20 | Usage |
| 21 | ===== |
| 22 | |
| 23 | Assume we have defined the ``coroutine_fn`` function |
| 24 | ``bdrv_co_foo(<some args>)`` and need a non-coroutine interface for it, |
| 25 | called ``bdrv_foo(<same args>)``. In this case the script can help. To |
| 26 | trigger the generation: |
| 27 | |
| 28 | 1. You need ``bdrv_foo`` declaration somewhere (for example, in |
| 29 | ``block/coroutines.h``) with the ``co_wrapper`` mark, |
| 30 | like this: |
| 31 | |
| 32 | .. code-block:: c |
| 33 | |
| 34 | int co_wrapper bdrv_foo(<some args>); |
| 35 | |
| 36 | 2. You need to feed this declaration to block-coroutine-wrapper script. |
| 37 | For this, add the .h (or .c) file with the declaration to the |
| 38 | ``input: files(...)`` list of ``block_gen_c`` target declaration in |
| 39 | ``block/meson.build`` |
| 40 | |
| 41 | You are done. During the build, coroutine wrappers will be generated in |
| 42 | ``<BUILD_DIR>/block/block-gen.c``. |
| 43 | |
| 44 | Links |
| 45 | ===== |
| 46 | |
| 47 | 1. The script location is ``scripts/block-coroutine-wrapper.py``. |
| 48 | |
| 49 | 2. Generic place for private ``co_wrapper`` declarations is |
| 50 | ``block/coroutines.h``, for public declarations: |
| 51 | ``include/block/block.h`` |
| 52 | |
| 53 | 3. The core API of generated coroutine wrappers is placed in |
| 54 | (not generated) ``block/block-gen.h`` |