diff options
| author | Tyge Løvset <[email protected]> | 2023-02-23 12:38:38 +0100 |
|---|---|---|
| committer | Tyge Løvset <[email protected]> | 2023-02-23 12:38:38 +0100 |
| commit | 01f09f3c2f34ae960b091f6d4063750bccd3e777 (patch) | |
| tree | 4ead1e1a6c89e74997283c5899285929a3c030be /include | |
| parent | 4ff4c8d352f76b658214029988eab7ce1d69efe8 (diff) | |
| download | STC-modified-01f09f3c2f34ae960b091f6d4063750bccd3e777.tar.gz STC-modified-01f09f3c2f34ae960b091f6d4063750bccd3e777.zip | |
Renamed cco.h to coroutine.h
Diffstat (limited to 'include')
| -rw-r--r-- | include/stc/algo/coroutine.h (renamed from include/stc/algo/cco.h) | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/include/stc/algo/cco.h b/include/stc/algo/coroutine.h index c94382b1..cf7acc16 100644 --- a/include/stc/algo/cco.h +++ b/include/stc/algo/coroutine.h @@ -31,7 +31,6 @@ * To use these macros to define a coroutine, you need to write a * function that looks something like this: * - * [Re-entrant version using an explicit context structure] * * int ascending(cco_handle* ctx) { * cco_context(ctx, @@ -44,12 +43,12 @@ * * cco_finish:; // add this to support cco_stop! * ); + * * return -1; * } * - * In the re-entrant version, you need to declare your persistent - * variables by the `cco_context' macro. This macro takes the - * cco_handle as first parameter. + * You declare your persistent variables with the `cco_context' + * macro. This macro takes the cco_handle as first parameter. * * Note that the context variable is set back to zero when the * coroutine terminates (by cco_stop, or by control reaching @@ -63,42 +62,43 @@ * case statements instead. That's why you can't put a cco_yield() * inside a switch-statement. * - * The re-entrant macros will malloc() the state structure on first - * call, and free() it when end is reached. If you want to - * abort in the middle, you can use, the caller should call the - * coroutine with `cco_stop(&ctx)' as parameter instead of &ctx alone. + * The macros will malloc() the state structure on first call, and + * free() it when end is reached. If you want to abort in the middle, + * the caller must call the coroutine with `cco_stop(&ctx)' as + * parameter instead of &ctx. + * * * Ground rules: * - never put `cco_yield' within an explicit `switch'. * - never put two `cco_yield' statements on the same source line. * - add `cco_finish:' label at the end of the coroutine, before * any cleanup code. Required to support cco_stop(ctx) argument. + * - in order to stop before all items are consumed, call the + * coroutine with `cco_stop(&handle)' as argument at the end. * * The caller of a re-entrant coroutine must provide a context * variable: * * void main(void) { - * cco_handle z = 0; + * cco_handle hnd = 0; * for (;;) { - * int x = ascending(&z); - * if (!z) break; + * int x = ascending(&hnd); + * if (x == 5) cco_stop(&hnd); + * if (!hnd) break; * printf("got number %d\n", x); * - * // stop if x == 5: - * if (x == 5) ascending(cco_stop(&z)); * } * } */ - -#ifndef COROUTINE_H -#define COROUTINE_H +#ifndef STC_COROUTINE_INCLUDED +#define STC_COROUTINE_INCLUDED #include <stdlib.h> #include <assert.h> /* * `c_' macros for re-entrant coroutines. */ -typedef struct { +typedef struct ccoHandle { int cco_line; } *cco_handle; @@ -116,19 +116,19 @@ typedef struct { struct ccoContext *ctx = *_ccoparam; \ switch (ctx->cco_line) { \ case 0: __VA_ARGS__ break; \ - default: assert(!"cco_finish: missing"); \ + default: assert(!"missing cco_finish:"); \ } \ free(ctx), *_ccoparam = NULL -#define cco_yield(ret) \ +#define cco_yield(value) \ do { \ - (*_ccoparam)->cco_line = __LINE__; return ret; \ + (*_ccoparam)->cco_line = __LINE__; return value; \ case __LINE__:; \ } while (0) #define cco_finish case -1 -#define cco_stop(ctx) \ - ((*(ctx))->cco_line = -1, (ctx)) +static inline cco_handle* cco_stop(cco_handle* handle) + { (*handle)->cco_line = -1; return handle; } -#endif /* COROUTINE_H */ +#endif // STC_COROUTINE_INCLUDED |
