hiasync 0.2.2

Supports only single-threaded asynchronous runtime
Documentation
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};

/// `LocalWaker::waker(&mut Context<'_>)`来替代`Context::waker`.
///
/// core::task::Waker支持Send Sync, 不适合单线程下使用.
/// `Context::waker`返回值无法提供唤醒功能.
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
        //unsafe { task::Waker::new(self as *const _ as *const (), &WAKER_VTBLE) }
    }

    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 ()) {
    // do nothing
}

unsafe fn waker_wake_by_ref(_this: *const ()) {
    // do nothing
}

unsafe fn waker_drop(_this: *const ()) {
    // do nothing
}

const WAKER_VTBLE: RawWakerVTable =
    RawWakerVTable::new(waker_clone, waker_wake, waker_wake_by_ref, waker_drop);