To pass data between the caller and the coroutine, use mco_push inside the coroutine (or in the caller) and mco_pop to retrieve it. This is useful for sending parameters into a coroutine or receiving results from a mco_yield.
In the example below, the coroutine receives a max value via mco_pop, calculates Fibonacci numbers, and sends them back to the caller using mco_push before yielding.
#define MINICORO_IMPL
#include "minicoro.h"
#include <stdio.h>
#include <stdlib.h>
static void fail(const char* message, mco_result res) {
printf("%s: %s\n", message, mco_result_description(res));
exit(-1);
}
static void fibonacci_coro(mco_coro* co) {
unsigned long m = 1;
unsigned long n = 1;
/* Retrieve max value. */
unsigned long max;
mco_result res = mco_pop(co, &max, sizeof(max));
if(res != MCO_SUCCESS)
fail("Failed to retrieve coroutine storage", res);
while(1) {
/* Yield the next Fibonacci number. */
mco_push(co, &m, sizeof(m));
res = mco_yield(co);
if(res != MCO_SUCCESS)
fail("Failed to yield coroutine", res);
unsigned long tmp = m + n;
m = n;
n = tmp;
if(m >= max)
break;
}
mco_push(co, &m, sizeof(m));
}
int main() {
mco_coro* co;
mco_desc desc = mco_desc_init(fibonacci_coro, 0);
mco_result res = mco_create(&co, &desc);
if(res != MCO_SUCCESS)
fail("Failed to create coroutine", res);
unsigned long max = 1000000000;
mco_push(co, &max, sizeof(max));
int counter = 1;
while(mco_status(co) == MCO_SUSPENDED) {
res = mco_resume(co);
if(res != MCO_SUCCESS)
fail("Failed to resume coroutine", res);
unsigned long ret = 0;
res = mco_pop(co, &ret, sizeof(ret));
if(res != MCO_SUCCESS)
fail("Failed to retrieve coroutine storage", res);
printf("fib %d = %lu\n", counter, ret);
counter = counter + 1;
}
res = mco_destroy(co);
if(res != MCO_SUCCESS)
fail("Failed to destroy coroutine", res);
return 0;
}