55 lines
2.1 KiB
ReStructuredText
55 lines
2.1 KiB
ReStructuredText
|
=======================
|
||
|
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:
|
||
|
|
||
|
.. code-block:: c
|
||
|
|
||
|
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``
|