use crate::{Event, JoinHandle, SchedInfo, TaskImpl};
use alloc::rc::Rc;
use core::any::Any;
use core::cell::RefCell;
use core::future::Future;
use core::task::{self, Context, RawWaker, RawWakerVTable};
pub trait LocalWaker {
fn waker(this: &Self) -> &Waker;
fn waker_mut_ptr(this: &mut Self) -> *mut Waker;
fn waker_mut(this: &mut Self) -> &mut Waker {
unsafe { &mut *LocalWaker::waker_mut_ptr(this) }
}
}
impl LocalWaker for Context<'_> {
fn waker(this: &Self) -> &Waker {
let ptr: *const task::Waker = this.waker();
unsafe { &*ptr.cast::<Waker>() }
}
fn waker_mut_ptr(this: &mut Self) -> *mut Waker {
let ptr: *const task::Waker = this.waker();
ptr.cast_mut().cast::<Waker>()
}
}
#[repr(C)]
pub struct Waker {
waker: task::Waker,
info: Rc<RefCell<SchedInfo>>,
task_id: u64,
}
impl Clone for Waker {
fn clone(&self) -> Self {
Self {
waker: self.waker.clone(),
info: self.info.clone(),
task_id: self.task_id,
}
}
}
impl Waker {
pub(crate) fn new(info: Rc<RefCell<SchedInfo>>, task_id: u64) -> Self {
Self {
waker: unsafe { task::Waker::from_raw(RawWaker::new(core::ptr::null(), &WAKER_VTBLE)) },
info,
task_id,
}
}
pub(crate) fn task_waker(&self) -> &task::Waker {
&self.waker
}
pub(crate) fn task_id(&self) -> u64 {
self.task_id
}
pub(crate) fn task_new<T: Future + 'static>(&mut self, future: T) -> JoinHandle<T::Output> {
let (task, handle) = TaskImpl::with_info(future, &self.info);
self.info.borrow_mut().task_push(task);
handle
}
pub fn wake_by_ref(&self) {
self.info.borrow_mut().task_wake(self.task_id);
}
pub fn wake(self) {
self.wake_by_ref();
}
pub(crate) fn task_abort(&self, task_id: u64) {
self.info.borrow_mut().task_abort(task_id);
}
pub(crate) fn task_resume(&self, task_id: u64) {
self.info.borrow_mut().task_wake(task_id);
}
pub(crate) fn event_register(&self, event_id: u64) {
self.info
.borrow_mut()
.event_register(event_id, self.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()
}
pub(crate) fn notify_events(&self, events: &[Event<'static>]) {
self.info.borrow_mut().events_push(events);
}
pub(crate) fn info(&self) -> &Rc<RefCell<SchedInfo>> {
&self.info
}
}
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);