summaryrefslogtreecommitdiffhomepage
path: root/misc/examples/coroutines/filetask.c
blob: 28292801cd41e98a9054b5cc99457ed2d470f0d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// https://github.com/lewissbaker/cppcoro#taskt

#include <time.h>
#include <stdio.h>
#define i_static
#include <stc/cstr.h>
#include <stc/coroutine.h>

cco_task_struct(file_read,
    const char* path;
    cstr line;
    FILE* fp;
    cco_timer tm;
);

int file_read(struct file_read* co, cco_runtime* rt)
{
    cco_routine (co) {
        co->fp = fopen(co->path, "r");
        co->line = cstr_null;

        while (true) {
            // emulate async io: await 10ms per line
            cco_await_timer(&co->tm, 0.003);

            if (!cstr_getline(&co->line, co->fp))
                break;
            cco_yield();
        }
        
        cco_cleanup:
        fclose(co->fp);
        cstr_drop(&co->line);
        puts("done file_read");
    }
    return 0;
}

cco_task_struct(count_line,
    cstr path;
    struct file_read reader;
    int lineCount;
);

int count_line(struct count_line* co, cco_runtime* rt)
{
    cco_routine (co) {
        co->reader.cco_func = file_read;
        co->reader.path = cstr_str(&co->path);
        while (true)
        {
            // await for next CCO_YIELD (or CCO_DONE) in file_read()
            cco_await_task(&co->reader, rt, CCO_YIELD);
            if (rt->result == CCO_DONE) break;
            co->lineCount += 1;
            cco_yield();
        }
        
        cco_cleanup:
        cstr_drop(&co->path);
        puts("done count_line");
    }
    return 0;
}

int main(void)
{
    // Creates a new task
    struct count_line countTask = {
        .cco_func = count_line,
        .path = cstr_from(__FILE__),
    };

    // Execute coroutine as top-level blocking
    int loop = 0;
    cco_blocking_task(&countTask) { ++loop; }

    printf("line count = %d\n", countTask.lineCount);
    printf("exec count = %d\n", loop);
}