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
use crate::base::{on_idle, RuntimeLoop, RuntimeWaker};
use std::{
future::Future,
ops::ControlFlow,
sync::{Arc, Condvar, Mutex},
};
pub fn run<F: Future>(future: F) -> F::Output {
crate::base::run(&NoFrameworkRuntimeLoop::new(), future)
}
struct NoFrameworkRuntimeLoop(Arc<Waker>);
struct Waker {
is_wake: Mutex<bool>,
cv: Condvar,
}
impl NoFrameworkRuntimeLoop {
pub fn new() -> Self {
Self(Arc::new(Waker {
is_wake: Mutex::new(true),
cv: Condvar::new(),
}))
}
}
impl Default for NoFrameworkRuntimeLoop {
fn default() -> Self {
Self::new()
}
}
impl RuntimeLoop for NoFrameworkRuntimeLoop {
fn waker(&self) -> Arc<dyn RuntimeWaker> {
self.0.clone()
}
fn run<T>(&self, mut on_step: impl FnMut() -> ControlFlow<T>) -> T {
let mut is_wake = self.0.is_wake.lock().unwrap();
loop {
if *is_wake {
*is_wake = false;
drop(is_wake);
loop {
if let ControlFlow::Break(value) = on_step() {
return value;
}
if !on_idle() {
break;
}
}
is_wake = self.0.is_wake.lock().unwrap()
} else {
is_wake = self.0.cv.wait(is_wake).unwrap();
}
}
}
}
impl RuntimeWaker for Waker {
fn wake(&self) {
let mut is_wake = self.is_wake.lock().unwrap();
if !*is_wake {
*is_wake = true;
self.cv.notify_all();
}
}
}