Merge pull request #348 from embassy-rs/remove-portal
Remove Portal. Fixes #32
This commit is contained in:
commit
36402b5487
@ -3,7 +3,6 @@ mod drop_bomb;
|
|||||||
mod forever;
|
mod forever;
|
||||||
mod mutex;
|
mod mutex;
|
||||||
mod on_drop;
|
mod on_drop;
|
||||||
mod portal;
|
|
||||||
mod signal;
|
mod signal;
|
||||||
|
|
||||||
#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
|
#[cfg_attr(feature = "executor-agnostic", path = "waker_agnostic.rs")]
|
||||||
@ -14,7 +13,6 @@ pub use forever::*;
|
|||||||
pub mod mpsc;
|
pub mod mpsc;
|
||||||
pub use mutex::*;
|
pub use mutex::*;
|
||||||
pub use on_drop::*;
|
pub use on_drop::*;
|
||||||
pub use portal::*;
|
|
||||||
pub use signal::*;
|
pub use signal::*;
|
||||||
pub use waker::*;
|
pub use waker::*;
|
||||||
|
|
||||||
|
@ -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<T> {
|
|
||||||
state: UnsafeCell<State<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum State<T> {
|
|
||||||
None,
|
|
||||||
Running,
|
|
||||||
Waiting(*mut dyn FnMut(T)),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Portal<T> {
|
|
||||||
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<R> = 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<R> + 'a,
|
|
||||||
{
|
|
||||||
let bomb = DropBomb::new();
|
|
||||||
|
|
||||||
let signal = Signal::new();
|
|
||||||
let mut result: MaybeUninit<R> = 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() }
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user