Skip to main content

makepad_futures_legacy/executor/
enter.rs

1use std::{cell::Cell, fmt};
2
3thread_local! {
4    static ENTERED: Cell<bool> = Cell::new(false);
5}
6
7/// An RAII guard used to mark the current thread as no longer being within the scope of an
8/// executor when dropped.
9#[derive(Debug)]
10pub struct Enter {
11    _priv: (),
12}
13
14impl Drop for Enter {
15    fn drop(&mut self) {
16        ENTERED.with(|c| {
17            assert!(c.get());
18            c.set(false);
19        });
20    }
21}
22
23/// An error that occurs when attempting to run an executor within the scope of another executor on
24/// the same thread.
25#[derive(Debug)]
26pub struct EnterError {
27    _priv: (),
28}
29
30impl fmt::Display for EnterError {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        write!(f, "can't run an executor within the scope of another executor on the same thread")
33    }
34}
35
36/// Marks the current thread as being within the scope of an executor.
37/// 
38/// This is a helper function used to ensure that users don't accidentally run an executor within
39/// the scope of another executor on the same thread. Executors should call this function before
40/// they begin executing a task, and drop the returned RAII guard after they finished executing the
41/// task.
42pub fn enter() -> Result<Enter, EnterError> {
43    ENTERED.with(|entered| {
44        if entered.get() {
45            Err(EnterError { _priv: () })
46        } else {
47            entered.set(true);
48            Ok(Enter { _priv: () })
49        }
50    })
51}