use core::task::{RawWaker, RawWakerVTable, Waker};
use core::mem::forget;
use alloc::sync::Arc;
use crate::os::Semaphore;
use crate::traits::SemaphoreFn;
static VTABLE: RawWakerVTable = RawWakerVTable::new(
clone_waker,
wake_waker,
wake_by_ref_waker,
drop_waker,
);
unsafe fn clone_waker(ptr: *const ()) -> RawWaker {
unsafe { Arc::increment_strong_count(ptr as *const Semaphore) };
RawWaker::new(ptr, &VTABLE)
}
unsafe fn wake_waker(ptr: *const ()) {
let arc = unsafe { Arc::from_raw(ptr as *const Semaphore) };
arc.signal();
}
unsafe fn wake_by_ref_waker(ptr: *const ()) {
let arc = unsafe { Arc::from_raw(ptr as *const Semaphore) };
arc.signal();
forget(arc);
}
unsafe fn drop_waker(ptr: *const ()) {
unsafe { drop(Arc::from_raw(ptr as *const Semaphore)) };
}
pub(crate) fn waker_from_semaphore(sem: Arc<Semaphore>) -> Waker {
let ptr = Arc::into_raw(sem) as *const ();
unsafe { Waker::from_raw(RawWaker::new(ptr, &VTABLE)) }
}