diff options
| -rw-r--r-- | embassy/src/util/mod.rs | 2 | ||||
| -rw-r--r-- | embassy/src/util/portal.rs | 120 |
2 files changed, 0 insertions, 122 deletions
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 87d313e28..e66576b33 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs | |||
| @@ -3,7 +3,6 @@ mod drop_bomb; | |||
| 3 | mod forever; | 3 | mod forever; |
| 4 | mod mutex; | 4 | mod mutex; |
| 5 | mod on_drop; | 5 | mod on_drop; |
| 6 | mod portal; | ||
| 7 | mod signal; | 6 | mod signal; |
| 8 | 7 | ||
| 9 | #[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")] | 8 | #[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")] |
| @@ -14,7 +13,6 @@ pub use forever::*; | |||
| 14 | pub mod mpsc; | 13 | pub mod mpsc; |
| 15 | pub use mutex::*; | 14 | pub use mutex::*; |
| 16 | pub use on_drop::*; | 15 | pub use on_drop::*; |
| 17 | pub use portal::*; | ||
| 18 | pub use signal::*; | 16 | pub use signal::*; |
| 19 | pub use waker::*; | 17 | pub use waker::*; |
| 20 | 18 | ||
diff --git a/embassy/src/util/portal.rs b/embassy/src/util/portal.rs deleted file mode 100644 index 8ea481093..000000000 --- a/embassy/src/util/portal.rs +++ /dev/null | |||
| @@ -1,120 +0,0 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::mem; | ||
| 3 | use core::mem::MaybeUninit; | ||
| 4 | |||
| 5 | use crate::util::*; | ||
| 6 | |||
| 7 | /// Utility to call a closure across tasks. | ||
| 8 | pub struct Portal<T> { | ||
| 9 | state: UnsafeCell<State<T>>, | ||
| 10 | } | ||
| 11 | |||
| 12 | enum State<T> { | ||
| 13 | None, | ||
| 14 | Running, | ||
| 15 | Waiting(*mut dyn FnMut(T)), | ||
| 16 | } | ||
| 17 | |||
| 18 | impl<T> Portal<T> { | ||
| 19 | pub const fn new() -> Self { | ||
| 20 | Self { | ||
| 21 | state: UnsafeCell::new(State::None), | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | pub fn call(&self, val: T) { | ||
| 26 | unsafe { | ||
| 27 | match *self.state.get() { | ||
| 28 | State::None => {} | ||
| 29 | State::Running => panic!("Portall::call() called reentrantly"), | ||
| 30 | State::Waiting(func) => (*func)(val), | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | pub async fn wait_once<'a, R, F>(&'a self, mut func: F) -> R | ||
| 36 | where | ||
| 37 | F: FnMut(T) -> R + 'a, | ||
| 38 | { | ||
| 39 | let bomb = DropBomb::new(); | ||
| 40 | |||
| 41 | let signal = Signal::new(); | ||
| 42 | let mut result: MaybeUninit<R> = MaybeUninit::uninit(); | ||
| 43 | let mut call_func = |val: T| { | ||
| 44 | unsafe { | ||
| 45 | let state = &mut *self.state.get(); | ||
| 46 | *state = State::None; | ||
| 47 | result.as_mut_ptr().write(func(val)) | ||
| 48 | }; | ||
| 49 | signal.signal(()); | ||
| 50 | }; | ||
| 51 | |||
| 52 | let func_ptr: *mut dyn FnMut(T) = &mut call_func as _; | ||
| 53 | let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) }; | ||
| 54 | |||
| 55 | unsafe { | ||
| 56 | let state = &mut *self.state.get(); | ||
| 57 | match state { | ||
| 58 | State::None => {} | ||
| 59 | _ => panic!("Multiple tasks waiting on same portal"), | ||
| 60 | } | ||
| 61 | *state = State::Waiting(func_ptr); | ||
| 62 | } | ||
| 63 | |||
| 64 | signal.wait().await; | ||
| 65 | |||
| 66 | bomb.defuse(); | ||
| 67 | |||
| 68 | unsafe { result.assume_init() } | ||
| 69 | } | ||
| 70 | |||
| 71 | pub async fn wait_many<'a, R, F>(&'a self, mut func: F) -> R | ||
| 72 | where | ||
| 73 | F: FnMut(T) -> Option<R> + 'a, | ||
| 74 | { | ||
| 75 | let bomb = DropBomb::new(); | ||
| 76 | |||
| 77 | let signal = Signal::new(); | ||
| 78 | let mut result: MaybeUninit<R> = MaybeUninit::uninit(); | ||
| 79 | let mut call_func = |val: T| { | ||
| 80 | unsafe { | ||
| 81 | let state = &mut *self.state.get(); | ||
| 82 | |||
| 83 | let func_ptr = match *state { | ||
| 84 | State::Waiting(p) => p, | ||
| 85 | _ => unreachable!(), | ||
| 86 | }; | ||
| 87 | |||
| 88 | // Set state to Running while running the function to avoid reentrancy. | ||
| 89 | *state = State::Running; | ||
| 90 | |||
| 91 | *state = match func(val) { | ||
| 92 | None => State::Waiting(func_ptr), | ||
| 93 | Some(res) => { | ||
| 94 | result.as_mut_ptr().write(res); | ||
| 95 | signal.signal(()); | ||
| 96 | State::None | ||
| 97 | } | ||
| 98 | }; | ||
| 99 | }; | ||
| 100 | }; | ||
| 101 | |||
| 102 | let func_ptr: *mut dyn FnMut(T) = &mut call_func as _; | ||
| 103 | let func_ptr: *mut dyn FnMut(T) = unsafe { mem::transmute(func_ptr) }; | ||
| 104 | |||
| 105 | unsafe { | ||
| 106 | let state = &mut *self.state.get(); | ||
| 107 | match *state { | ||
| 108 | State::None => {} | ||
| 109 | _ => panic!("Multiple tasks waiting on same portal"), | ||
| 110 | } | ||
| 111 | *state = State::Waiting(func_ptr); | ||
| 112 | } | ||
| 113 | |||
| 114 | signal.wait().await; | ||
| 115 | |||
| 116 | bomb.defuse(); | ||
| 117 | |||
| 118 | unsafe { result.assume_init() } | ||
| 119 | } | ||
| 120 | } | ||
