rt_local_core/runtime/
core.rs

1use crate::base::{on_idle, RuntimeLoop, RuntimeWaker};
2use std::{
3    future::Future,
4    ops::ControlFlow,
5    sync::{Arc, Condvar, Mutex},
6};
7
8/// Executes the specified future and blocks until it completes.
9pub 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}