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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use crate::*;
use ctx::*;
use ptr::*;
use scheduler::*;
pub struct Fiber<T> {
handle: ThreadHandle<T>,
}
impl<T> Fiber<T> {
pub fn new<F: FnOnce() -> T + Clone + 'static>(closure: F) -> Self {
Self {
handle: RUNTIME.with(|rt| {
rt.get()
.spawn_not_schedule(|closure, _| closure(), (Box::new(closure), ()))
}),
}
}
pub fn new_capture<F: 'static, A: 'static + ApplyTo<F, Result = T> + Clone>(
closure: F,
args: A,
) -> Self {
Self {
handle: RUNTIME.with(|rt| rt.get().spawn_not_schedule(closure, args)),
}
}
fn get_thread(&self) -> Ptr<Context> {
self.handle.thread()
}
pub fn yield_(&self) {
crate::yield_thread();
}
pub fn start(&self) -> Result<(), &'static str> {
if self.get_thread().terminated {
return Err("Fiber terminated");
}
self.get_thread().scheduler.get().resume(self.get_thread());
Ok(())
}
pub fn join(self) -> Result<T, Box<dyn std::any::Any>>
where
T: 'static,
{
match self.handle.join() {
Ok(value) => Ok(value),
Err(e) => Err(e),
}
}
pub fn is_alive(&self) -> bool {
!self.handle.thread().terminated
}
pub fn suspend(&self) {
self.get_thread()
.scheduler
.get()
.suspend_thread(self.get_thread());
}
}