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``
							 |