hirun 0.1.1

rust异步运行框架
Documentation
use super::{worker_from, RawTask, Worker};
use crate::event::Scheduler;
use core::ptr::NonNull;
use core::task::{RawWaker, RawWakerVTable, Waker};
use hioff::{container_of, container_of_mut};

impl RawTask {
    pub(crate) fn task_waker(&self) -> Waker {
        let raw_waker = RawWaker::new((self as *const Self).cast::<()>(), &TASKWAKER_VTABLE);
        unsafe { Waker::from_raw(raw_waker) }
    }
}

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

unsafe fn waker_clone(this: *const ()) -> RawWaker {
    let task = unsafe { &*this.cast::<RawTask>() };
    task.inc_ref();
    RawWaker::new(this, &RAWWAKER_VTABLE)
}

unsafe fn waker_wake(this: *const ()) {
    let task = unsafe { &*this.cast::<RawTask>() };
    task.wake();
    task.dec_ref();
}

unsafe fn waker_wake_by_ref(this: *const ()) {
    let task = unsafe { &*this.cast::<RawTask>() };
    task.wake();
}

unsafe fn waker_drop(this: *const ()) {
    let task = unsafe { &*this.cast::<RawTask>() };
    task.dec_ref();
}

const TASKWAKER_VTABLE: RawWakerVTable =
    RawWakerVTable::new(waker_clone, waker_wake_by_ref, waker_wake_by_ref, task_waker_drop);

unsafe fn task_waker_drop(_this: *const ()) {}

pub(crate) struct TaskWaker<'a> {
    pub(crate) waker: Waker,
    pub(crate) task: NonNull<RawTask>,
    pub(crate) sched: &'a mut Scheduler,
}

impl<'a> TaskWaker<'a> {
    pub(crate) fn new(task: &mut RawTask, sched: &'a mut Scheduler) -> Self {
        let worker = unsafe { worker_from(sched) };
        worker.set_current_task(Some(NonNull::from(&*task)));
        Self {
            waker: task.task_waker(),
            task: NonNull::from(task),
            sched,
        }
    }
}

impl Drop for TaskWaker<'_> {
    fn drop(&mut self) {
        let worker = unsafe { worker_from(self.sched) };
        worker.set_current_task(None);
    }
}

pub(crate) unsafe fn task_from_waker(waker: &Waker) -> NonNull<RawTask> {
    let task_waker = unsafe { container_of!(waker, TaskWaker, waker) };
    task_waker.task
}

#[allow(dead_code)]
pub(crate) unsafe fn worker_from_waker(waker: &Waker) -> NonNull<Worker> {
    let task_waker = unsafe { container_of!(waker, TaskWaker, waker) };
    NonNull::new_unchecked(task_waker.sched.private_data().cast_mut().cast())
}

pub(crate) unsafe fn sched_from_waker(waker: &Waker) -> NonNull<Scheduler> {
    let task_waker = unsafe { container_of_mut!(waker, TaskWaker, waker) };
    NonNull::from(&*task_waker.sched)
}