wta_reactor/
lib.rs

1#![forbid(unsafe_code)]
2#![warn(clippy::pedantic)]
3#![allow(clippy::missing_errors_doc)]
4
5use std::{cell::RefCell, sync::Arc};
6
7mod io;
8pub mod net;
9pub mod timers;
10
11#[derive(Default)]
12pub struct Reactor {
13    os: io::Os,
14    timers: timers::Queue,
15}
16
17impl Reactor {
18    // this is run by any thread that currently is not busy.
19    // It manages the timers and OS polling in order to wake up tasks
20    pub fn book_keeping(&self) {
21        // get the current task timers that have elapsed and insert them into the ready tasks
22        for task in &self.timers {
23            task.wake();
24        }
25
26        // get the OS events
27        self.os.process();
28    }
29
30    /// register this executor on the current thread
31    pub fn register(self: &Arc<Self>) {
32        REACTOR.with(|reactor| *reactor.borrow_mut() = Some(self.clone()));
33    }
34}
35
36thread_local! {
37    static REACTOR: RefCell<Option<Arc<Reactor>>> = const { RefCell::new(None) };
38}
39
40pub(crate) fn context<R>(f: impl FnOnce(&Arc<Reactor>) -> R) -> R {
41    REACTOR.with(|r| {
42        let r = r.borrow();
43        let r = r.as_ref().expect("called outside of an reactor context");
44        f(r)
45    })
46}