hiasync 0.1.1

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

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