Allow capturing references in the future passed to Deterministic::run

This commit is contained in:
Antonio Scandurra 2022-03-01 11:59:58 +01:00
parent 7ce6f23ed4
commit 8390f04e7d

View file

@ -156,9 +156,30 @@ impl Deterministic {
task task
} }
fn run(&self, cx_id: usize, main_future: AnyLocalFuture) -> Box<dyn Any> { fn run<'a>(
&self,
cx_id: usize,
main_future: Pin<Box<dyn 'a + Future<Output = Box<dyn Any>>>>,
) -> Box<dyn Any> {
let woken = Arc::new(AtomicBool::new(false)); let woken = Arc::new(AtomicBool::new(false));
let mut main_task = self.spawn_from_foreground(cx_id, main_future, true);
let state = self.state.clone();
let unparker = self.parker.lock().unparker();
let (runnable, mut main_task) = unsafe {
async_task::spawn_unchecked(main_future, move |runnable| {
let mut state = state.lock();
state
.scheduled_from_foreground
.entry(cx_id)
.or_default()
.push(ForegroundRunnable {
runnable,
main: true,
});
unparker.unpark();
})
};
runnable.schedule();
loop { loop {
if let Some(result) = self.run_internal(woken.clone(), Some(&mut main_task)) { if let Some(result) = self.run_internal(woken.clone(), Some(&mut main_task)) {
@ -330,13 +351,13 @@ impl Foreground {
Task::local(any_task) Task::local(any_task)
} }
pub fn run<T: 'static>(&self, future: impl 'static + Future<Output = T>) -> T { pub fn run<T: 'static>(&self, future: impl Future<Output = T>) -> T {
let future = any_local_future(future); let future = async move { Box::new(future.await) as Box<dyn Any> }.boxed_local();
let any_value = match self { let result = match self {
Self::Deterministic { cx_id, executor } => executor.run(*cx_id, future), Self::Deterministic { cx_id, executor } => executor.run(*cx_id, future),
Self::Platform { .. } => panic!("you can't call run on a platform foreground executor"), Self::Platform { .. } => panic!("you can't call run on a platform foreground executor"),
}; };
*any_value.downcast().unwrap() *result.downcast().unwrap()
} }
pub fn run_until_parked(&self) { pub fn run_until_parked(&self) {