133 lines2.8 KB
Newer
Older
-
+
commited
{line.log.rev}
on
11 months ago
4
1
#include "generator.h"
2
#include "coroutine.h"
3
#include <stdlib.h>
4
#include <stdio.h>
5
#include <assert.h>
10 months ago
6
#include "cor_platform.h"
11 months ago
4
7
8
11 months ago
9
_Cor_thread_local Generator *g_active_generator = NULL;
10
11 months ago
11
2 months ago
12
static void
13
on_yield_gen(
11 months ago
14
void *this
15
){
2 months ago
16
(void)this;
11 months ago
4
17
}
18
11 months ago
19
2 months ago
20
static void
21
on_yield_gen_caller(
11 months ago
22
void *this
23
){
11 months ago
24
(void)this;
25
}
26
11 months ago
27
2 months ago
28
static void *
29
do_start(
11 months ago
30
void *this
31
){
11 months ago
4
32
Generator *gen = (Generator *)this;
11 months ago
33
g_active_generator = this;
11 months ago
4
34
assert(gen->state == Generator_Running || gen->state == Generator_Deleting);
35
void *value;
36
if (gen->state == Generator_Running){
11 months ago
37
g_active_generator = gen;
11 months ago
4
38
value = gen->start(gen->param);
11 months ago
39
g_active_generator = NULL;
11 months ago
4
40
} else {
41
// we are being deleted
42
value = NULL;
43
}
44
gen->state = Generator_Complete;
3 months ago
45
Coroutine_NS(Continue)(gen->caller, value, true);
11 months ago
4
46
return value;
47
}
48
11 months ago
49
2 months ago
50
void
51
Generator_ctor(
11 months ago
52
Generator *gen,
2 months ago
53
size_t min_stack,
54
size_t min_stack_headroom,
11 months ago
55
void *(*start)(void *),
56
void *param
57
){
11 months ago
4
58
gen->start = start;
59
gen->param = param;
2 months ago
60
gen->coroutine = Coroutine_NS(New)(min_stack, min_stack_headroom, do_start);
2 months ago
61
gen->yielded_coroutine = gen->coroutine;
11 months ago
4
62
gen->state = Generator_Running;
11 months ago
63
}
64
65
2 months ago
66
Generator *
67
Generator_New(
68
size_t min_stack,
69
size_t min_stack_headroom,
11 months ago
70
void *(*start)(void *),
71
void *param
72
){
73
Generator *gen = malloc(sizeof(Generator));
2 months ago
74
Generator_ctor(gen, min_stack, min_stack_headroom, start, param);
11 months ago
4
75
return gen;
76
}
77
11 months ago
78
2 months ago
79
void
80
Generator_dtor(
11 months ago
81
Generator *gen
82
){
11 months ago
4
83
assert(gen->state != Generator_Deleting);
84
if (gen->state == Generator_Running){
85
gen->state = Generator_Deleting;
3 months ago
86
gen->caller = Coroutine_NS(GetActive)();
2 months ago
87
Coroutine_NS(Continue)(gen->yielded_coroutine, gen, true);
3 months ago
88
Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
11 months ago
4
89
}
90
assert(gen->state == Generator_Complete);
3 months ago
91
Coroutine_NS(Delete)(gen->coroutine);
11 months ago
92
}
93
2 months ago
94
void
95
Generator_Delete(
11 months ago
96
Generator *gen
97
){
98
Generator_dtor(gen);
11 months ago
4
99
free(gen);
100
}
101
11 months ago
102
2 months ago
103
bool
104
Generator_Next(
11 months ago
105
Generator *gen,
106
void **value
107
){
11 months ago
4
108
assert(gen->state != Generator_Deleting);
109
if (gen->state == Generator_Complete){
110
return false;
111
}
3 months ago
112
gen->caller = Coroutine_NS(GetActive)();
2 months ago
113
Coroutine_NS(Continue)(gen->yielded_coroutine, gen, true);
3 months ago
114
*value = Coroutine_NS(Yield)(NULL, on_yield_gen_caller, gen);
115
return Coroutine_NS(IsRunning)(gen->coroutine);
11 months ago
4
116
}
117
11 months ago
118
2 months ago
119
bool
120
Generator_Yield(
11 months ago
121
void *value
122
)
11 months ago
4
123
{
11 months ago
124
assert(g_active_generator);
125
Generator *gen = g_active_generator;
126
g_active_generator = NULL;
2 months ago
127
gen->yielded_coroutine = Coroutine_NS(GetActive)();
128
Coroutine_NS(Continue)(gen->caller, value, true);
129
Coroutine_NS(Yield)(value, on_yield_gen, NULL);
11 months ago
130
g_active_generator = gen;
11 months ago
4
131
return gen->state == Generator_Running;
132
}
133