This new annotation starts just a function wrapper that creates a new coroutine. It assumes the caller is not a coroutine. It will be the default annotation to be used in the future. This is much better as c_w_mixed, because it is clear if the caller is a coroutine or not, and provides the advantage of automating the code creation. In the future all c_w_mixed functions will be substituted by co_wrapper. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru> Message-Id: <20221128142337.657646-11-eesposit@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
		
			
				
	
	
		
			55 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			55 lines
		
	
	
		
			2.0 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 ``co_wrapper`` mark,
 | 
						|
   like this:
 | 
						|
 | 
						|
.. code-block:: c
 | 
						|
 | 
						|
    int 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 ``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``
 |