use crate::{JoinHandle, JoinHandleInner};
use std::future::Future;
use std::pin::Pin;
use std::rc::{Rc, Weak};
use std::task::{Context, Poll};
pub(crate) trait Task {
fn get_id(&self) -> u64;
fn run(&mut self, ctx: &mut Context<'_>) -> Poll<()>;
}
pub(crate) struct TaskImpl<T: Future> {
id: u64,
future: T,
handle: Weak<JoinHandleInner<T>>,
}
impl<T: Future + 'static> TaskImpl<T> {
pub(crate) fn with_id(future: T, id: u64) -> (Box<dyn Task>, JoinHandle<T>) {
let handle = JoinHandle::new();
let task = Box::new(TaskImpl {
id,
future,
handle: Rc::<JoinHandleInner<T>>::downgrade(handle.inner()),
});
(task, handle)
}
}
impl<T: Future> Task for TaskImpl<T> {
fn get_id(&self) -> u64 {
self.id
}
fn run(&mut self, ctx: &mut Context<'_>) -> Poll<()> {
let pin = unsafe { Pin::new_unchecked(&mut self.future) };
match pin.poll(ctx) {
Poll::Pending => Poll::Pending,
Poll::Ready(output) => {
if let Some(handle) = self.handle.upgrade() {
handle.set_output(output);
}
Poll::Ready(())
}
}
}
}