rt_local_core/runtime/
core.rs1use crate::base::{on_idle, RuntimeLoop, RuntimeWaker};
2use std::{
3 future::Future,
4 ops::ControlFlow,
5 sync::{Arc, Condvar, Mutex},
6};
7
8pub fn run<F: Future>(future: F) -> F::Output {
10 crate::base::run(&NoFrameworkRuntimeLoop::new(), future)
11}
12
13struct NoFrameworkRuntimeLoop(Arc<Waker>);
14
15struct Waker {
16 is_wake: Mutex<bool>,
17 cv: Condvar,
18}
19
20impl NoFrameworkRuntimeLoop {
21 pub fn new() -> Self {
22 Self(Arc::new(Waker {
23 is_wake: Mutex::new(true),
24 cv: Condvar::new(),
25 }))
26 }
27}
28
29impl Default for NoFrameworkRuntimeLoop {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl RuntimeLoop for NoFrameworkRuntimeLoop {
36 fn waker(&self) -> Arc<dyn RuntimeWaker> {
37 self.0.clone()
38 }
39 fn run<T>(&self, mut on_step: impl FnMut() -> ControlFlow<T>) -> T {
40 let mut is_wake = self.0.is_wake.lock().unwrap();
41 loop {
42 if *is_wake {
43 *is_wake = false;
44 drop(is_wake);
45 loop {
46 if let ControlFlow::Break(value) = on_step() {
47 return value;
48 }
49 if !on_idle() {
50 break;
51 }
52 }
53 is_wake = self.0.is_wake.lock().unwrap()
54 } else {
55 is_wake = self.0.cv.wait(is_wake).unwrap();
56 }
57 }
58 }
59}
60
61impl RuntimeWaker for Waker {
62 fn wake(&self) {
63 let mut is_wake = self.is_wake.lock().unwrap();
64 if !*is_wake {
65 *is_wake = true;
66 self.cv.notify_all();
67 }
68 }
69}