[Sheepdog] [PATCH v3 1/2] introduce coroutine
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Fri Dec 2 06:31:45 CET 2011
At Mon, 28 Nov 2011 03:09:06 +0900,
MORITA Kazutaka wrote:
>
> We have many works that need to be processed cooperatively
> (e.g. object recovery, data I/Os, cluster management). This library
> will enable us to implement them simply and elegantly.
>
> These files are copied from Accord project:
> https://github.com/collie/accord
Applied this series after adding the following comments, which are
borrowed from QEMU commit log, to explain how to use coroutines in
more detail:
Asynchronous code is becoming very complex. At the same time
synchronous code is growing because it is convenient to write.
Sometimes duplicate code paths are even added, one synchronous and the
other asynchronous. This patch introduces coroutines which allow code
that looks synchronous but is asynchronous under the covers.
A coroutine has its own stack and is therefore able to preserve state
across blocking operations, which traditionally require callback
functions and manual marshalling of parameters.
Creating and starting a coroutine is easy:
coroutine = coroutine_create(my_coroutine);
coroutine_enter(coroutine, my_data);
The coroutine then executes until it returns or yields:
void my_coroutine(void *opaque) {
MyData *my_data = opaque;
/* do some work */
coroutine_yield();
/* do some more work */
}
Yielding switches control back to the caller of coroutine_enter().
This is typically used to switch back to the main thread's event
loop after issuing an asynchronous I/O request. The request
callback will then invoke coroutine_enter() once more to switch
back to the coroutine.
Note that if coroutines are used only from the main thread, they
will never execute concurrently. This makes programming with
coroutines easier than with threads. Race conditions cannot occur
since only one coroutine may be active at any time. Other
coroutines can only run across yield.
Thanks,
Kazutaka
More information about the sheepdog
mailing list