-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathcoroutine.cc
92 lines (76 loc) · 1.68 KB
/
coroutine.cc
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
81
82
83
84
85
86
87
88
89
90
91
92
#include "coroutine.h"
#include "timer.h"
using study::Coroutine;
Coroutine* Coroutine::current = nullptr;
long Coroutine::last_cid = 0;
std::unordered_map<long, Coroutine*> Coroutine::coroutines;
size_t Coroutine::stack_size = DEFAULT_C_STACK_SIZE;
st_coro_on_swap_t Coroutine::on_yield = nullptr;
st_coro_on_swap_t Coroutine::on_resume = nullptr;
st_coro_on_swap_t Coroutine::on_close = nullptr;
void* Coroutine::get_current_task()
{
return current ? current->get_task() : nullptr;
}
void* Coroutine::get_task()
{
return task;
}
Coroutine* Coroutine::get_current()
{
return current;
}
void Coroutine::set_task(void *_task)
{
task = _task;
}
long Coroutine::create(coroutine_func_t fn, void* args)
{
return (new Coroutine(fn, args))->run();
}
void Coroutine::yield()
{
assert(current == this);
on_yield(task);
current = origin;
ctx.swap_out();
}
void Coroutine::resume()
{
assert(current != this);
on_resume(task);
origin = current;
current = this;
ctx.swap_in();
if (ctx.is_end())
{
assert(current == this);
on_close(task);
current = origin;
coroutines.erase(cid);
delete this;
}
}
static void sleep_timeout(void *param)
{
((Coroutine *) param)->resume();
}
int Coroutine::sleep(double seconds)
{
Coroutine* co = Coroutine::get_current();
timer_manager.add_timer(seconds * Timer::SECOND, sleep_timeout, (void*)co);
co->yield();
return 0;
}
void Coroutine::set_on_yield(st_coro_on_swap_t func)
{
on_yield = func;
}
void Coroutine::set_on_resume(st_coro_on_swap_t func)
{
on_resume = func;
}
void Coroutine::set_on_close(st_coro_on_swap_t func)
{
on_close = func;
}