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}