use std::future::Future;
use std::pin::Pin;
use std::task::{Context, Poll};
use crate::context::{LocalKey, LocalKeyImmutable};
#[derive(Debug)]
pub(crate) struct TaskLocalFuture<V: 'static, F> {
pub(crate) slot: Option<V>,
pub(crate) local_key: &'static LocalKey<V>,
pub(crate) future: F,
}
#[derive(Debug)]
pub(crate) struct TaskLocalImmutableFuture<V: 'static, F> {
pub(crate) slot: Option<V>,
pub(crate) local_key: &'static LocalKeyImmutable<V>,
pub(crate) future: F,
}
impl<V, F> TaskLocalFuture<V, F> {
}
impl<V, F> TaskLocalImmutableFuture<V, F> {
}
impl<V, F> Future for TaskLocalFuture<V, F>
where
V: Unpin,
F: Future,
{
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let (future, slot, local_key) = unsafe {
let this = self.get_unchecked_mut();
let future = Pin::new_unchecked(&mut this.future);
let slot = Pin::new_unchecked(&mut this.slot);
let local_key = Pin::new_unchecked(&mut this.local_key);
(future, slot, local_key)
};
let mut_slot = Pin::get_mut(slot);
let value = mut_slot.take().expect("No value in slot");
let old_value = local_key.0.replace(Some(value));
assert!(old_value.is_none(), "Task-local already set");
let r = future.poll(cx);
let value = local_key.0.replace(None).expect("No value in slot");
mut_slot.replace(value);
r
}
}
impl<V, F> Future for TaskLocalImmutableFuture<V, F>
where
V: Unpin,
F: Future,
{
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let (future, slot, local_key) = unsafe {
let this = self.get_unchecked_mut();
let future = Pin::new_unchecked(&mut this.future);
let slot = Pin::new_unchecked(&mut this.slot);
let local_key = Pin::new_unchecked(&mut this.local_key);
(future, slot, local_key)
};
let mut_slot = Pin::get_mut(slot);
let value = mut_slot.take().expect("No value in slot");
let old_value = local_key.0.replace(Some(value));
assert!(old_value.is_none(), "Task-local already set");
let r = future.poll(cx);
let value = local_key.0.replace(None).expect("No value in slot");
mut_slot.replace(value);
r
}
}