use crate::queue::FnOnceQueue;
use crate::{task::Task, Stakker};
use std::cell::{Cell, UnsafeCell};
use std::marker::PhantomData;
use std::mem;
thread_local!(
#[allow(clippy::missing_const_for_thread_local)]
static QUEUE: UnsafeCell<FnOnceQueue<Stakker>> = UnsafeCell::new(FnOnceQueue::new());
static TASK: Cell<Option<Task>> = const { Cell::new(None) };
);
#[derive(Clone)]
pub struct DeferrerAux(PhantomData<*const u8>);
impl DeferrerAux {
pub(crate) fn new() -> Self {
Self(PhantomData)
}
pub(crate) fn swap_queue(&self, queue: &mut FnOnceQueue<Stakker>) {
#[allow(clippy::swap_ptr_to_ref)]
unsafe {
let _ = QUEUE.try_with(move |qref| mem::swap(&mut *qref.get(), queue));
}
}
#[inline]
pub fn defer(&self, f: impl FnOnce(&mut Stakker) + 'static) {
unsafe {
let _ = QUEUE.try_with(|qref| (*qref.get()).push(f));
}
}
#[inline]
pub fn task_replace(&self, task: Option<Task>) -> Option<Task> {
TASK.try_with(move |tref| tref.replace(task))
.unwrap_or(None)
}
}