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