use crate::{JoinHandle, SchedInfo, Task, TaskImpl};
use std::any::Any;
use std::cell::RefCell;
use std::future::Future;
use std::mem;
use std::rc::Rc;
use std::task::{self, Context, RawWaker, RawWakerVTable};
pub trait LocalWaker {
fn waker(this: &Self) -> &Waker;
fn waker_mut(this: &mut Self) -> &mut Waker;
}
impl LocalWaker for Context<'_> {
fn waker(this: &Self) -> &Waker {
let waker = this.waker().data();
unsafe { &*waker.cast::<Waker>() }
}
fn waker_mut(this: &mut Self) -> &mut Waker {
let waker = this.waker().data().cast_mut();
unsafe { &mut *waker.cast::<Waker>() }
}
}
pub struct Waker {
info: Rc<RefCell<SchedInfo>>,
tasks: Vec<Box<dyn Task>>,
current_task_id: u64,
task_id: u64,
}
impl Clone for Waker {
fn clone(&self) -> Self {
Self {
info: self.info.clone(),
tasks: vec![],
current_task_id: self.current_task_id,
task_id: 0,
}
}
}
impl Waker {
pub(crate) fn new(info: Rc<RefCell<SchedInfo>>, current_task_id: u64, task_id: u64) -> Self {
Self {
info,
current_task_id,
task_id,
tasks: vec![],
}
}
pub(crate) fn task_waker(&self) -> task::Waker {
unsafe { task::Waker::new(self as *const _ as *const (), &WAKER_VTBLE) }
}
pub(crate) fn current_task_id(&self) -> u64 {
self.current_task_id
}
pub(crate) fn task_new<T: Future + 'static>(&mut self, future: T) -> JoinHandle<T> {
let (task, handle) = TaskImpl::with_id(future, self.task_id);
self.task_id += 1;
self.tasks.push(task);
handle
}
pub(crate) fn tasks_swap(&mut self, tasks: &mut Vec<Box<dyn Task>>) {
mem::swap(&mut self.tasks, tasks);
}
pub(crate) fn task_id(&self) -> u64 {
self.task_id
}
pub fn wake_by_ref(&self) {
self.info.borrow_mut().task_wake(self.current_task_id);
}
pub fn wake(self) {
self.wake_by_ref();
}
pub(crate) fn event_register(&self, event_id: u64) {
self.info
.borrow_mut()
.event_register(event_id, self.current_task_id);
}
pub(crate) fn event_unregister(&self, event_id: u64) {
self.info
.borrow_mut()
.event_unregister(event_id);
}
pub(crate) fn event_remove<'a>(&self, event_id: u64) -> Option<&'a dyn Any> {
self.info.borrow_mut().event_remove(event_id)
}
pub(crate) fn new_event_id(&self) -> u64 {
self.info.borrow_mut().new_event_id()
}
}
unsafe fn waker_clone(this: *const ()) -> RawWaker {
RawWaker::new(this, &WAKER_VTBLE)
}
unsafe fn waker_wake(_this: *const ()) {
}
unsafe fn waker_wake_by_ref(_this: *const ()) {
}
unsafe fn waker_drop(_this: *const ()) {
}
const WAKER_VTBLE: RawWakerVTable =
RawWakerVTable::new(waker_clone, waker_wake, waker_wake_by_ref, waker_drop);