use std::{future::Future, ptr::NonNull};
use dope_core::driver::{CompletionBackend, CurrentSlot};
use super::JoinHandle;
use super::TimerHeap;
use super::task_queue::TaskQueue;
#[derive(Clone, Copy)]
pub struct RuntimeHandles {
pub(crate) exec: NonNull<TaskQueue>,
pub(crate) timers: NonNull<TimerHeap>,
}
pub struct RuntimeCtx<B: CompletionBackend> {
slot: CurrentSlot<B>,
}
impl<B: CompletionBackend> Clone for RuntimeCtx<B> {
fn clone(&self) -> Self {
*self
}
}
impl<B: CompletionBackend> Copy for RuntimeCtx<B> {}
impl<B: CompletionBackend> RuntimeCtx<B> {
#[inline(always)]
pub(super) fn from_slot(slot: CurrentSlot<B>) -> Self {
Self { slot }
}
#[inline(always)]
pub fn driver(&self) -> &B::Driver {
unsafe { self.slot.driver().as_ref() }
}
#[inline(always)]
#[allow(clippy::mut_from_ref)]
pub fn driver_mut(&self) -> &mut B::Driver {
unsafe { &mut *self.slot.driver().as_ptr() }
}
#[inline(always)]
fn extra(&self) -> &RuntimeHandles {
unsafe { &*(self.slot.extra() as *const RuntimeHandles) }
}
pub fn spawn<F>(&self, fut: F) -> JoinHandle<F::Output>
where
F: Future + 'static,
F::Output: 'static,
{
unsafe { self.extra().exec.as_ref() }.spawn(fut)
}
pub(crate) fn timers(&self) -> NonNull<TimerHeap> {
self.extra().timers
}
}