diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 87d313e2..e66576b3 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs @@ -3,7 +3,6 @@ mod drop_bomb; mod forever; mod mutex; mod on_drop; -mod portal; mod signal; #[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")] @@ -14,7 +13,6 @@ pub use forever::*; pub mod mpsc; pub use mutex::*; pub use on_drop::*; -pub use portal::*; pub use signal::*; pub use waker::*; diff --git a/embassy/src/util/portal.rs b/embassy/src/util/portal.rs deleted file mode 100644 index 8ea48109..00000000 --- a/embassy/src/util/portal.rs +++ /dev/null @@ -1,120 +0,0 @@ -use core::cell::UnsafeCell; -use core::mem; -use core::mem::MaybeUninit; - -use crate::util::*; - -/// Utility to call a closure across tasks. -pub struct Portal { - state: UnsafeCell>, -} - -enum State { - None, - Running, - Waiting(*mut dyn FnMut(T)), -} - -impl Portal { - pub const fn new() -> Self { - Self { - state: UnsafeCell::new(State::None), - } - } - - pub fn call(&self, val: T) { - unsafe { - match *self.state.get() { - State::None => {} - State::Running => panic!("Portall::call() called reentrantly"), - State::Waiting(func) => (*func)(val), - } - } - } - - pub async fn wait_once<'a, R, F>(&'a self, mut func: F) -> R - where - F: FnMut(T) -> R + 'a, - { - let bomb = DropBomb::new(); - - let signal = Signal::new(); - let mut result: MaybeUninit = MaybeUninit::uninit(); - let mut call_func = |val: T| { - unsafe { - let state = &mut *self.state.get(); - *state = State::None; - result.as_mut_ptr().write(func(val)) - }; - signal.signal(()); - }; - - let func_ptr: *mut dyn FnMut(T) = &mut call_func as _; - let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) }; - - unsafe { - let state = &mut *self.state.get(); - match state { - State::None => {} - _ => panic!("Multiple tasks waiting on same portal"), - } - *state = State::Waiting(func_ptr); - } - - signal.wait().await; - - bomb.defuse(); - - unsafe { result.assume_init() } - } - - pub async fn wait_many<'a, R, F>(&'a self, mut func: F) -> R - where - F: FnMut(T) -> Option + 'a, - { - let bomb = DropBomb::new(); - - let signal = Signal::new(); - let mut result: MaybeUninit = MaybeUninit::uninit(); - let mut call_func = |val: T| { - unsafe { - let state = &mut *self.state.get(); - - let func_ptr = match *state { - State::Waiting(p) => p, - _ => unreachable!(), - }; - - // Set state to Running while running the function to avoid reentrancy. - *state = State::Running; - - *state = match func(val) { - None => State::Waiting(func_ptr), - Some(res) => { - result.as_mut_ptr().write(res); - signal.signal(()); - State::None - } - }; - }; - }; - - let func_ptr: *mut dyn FnMut(T) = &mut call_func as _; - let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) }; - - unsafe { - let state = &mut *self.state.get(); - match *state { - State::None => {} - _ => panic!("Multiple tasks waiting on same portal"), - } - *state = State::Waiting(func_ptr); - } - - signal.wait().await; - - bomb.defuse(); - - unsafe { result.assume_init() } - } -}