use std::sync::Arc;
#[derive(Clone, Debug)]
pub(crate) struct Tuning {
pub(crate) driver_interval: u32,
pub(crate) inbox_interval: u32,
pub(crate) max_io_events: usize,
pub(crate) lifo: bool,
pub(crate) hooks: ThreadHooks,
}
impl Default for Tuning {
fn default() -> Self {
Self {
driver_interval: super::shard::DRIVER_INTERVAL,
inbox_interval: super::shard::INBOX_INTERVAL,
max_io_events: usize::MAX,
lifo: true,
hooks: ThreadHooks::default(),
}
}
}
pub(crate) type Hook = Arc<dyn Fn() + Send + Sync>;
#[derive(Clone, Default)]
pub(crate) struct ThreadHooks {
pub(crate) start: Option<Hook>,
pub(crate) stop: Option<Hook>,
pub(crate) park: Option<Hook>,
pub(crate) unpark: Option<Hook>,
}
impl ThreadHooks {
pub(crate) fn started(&self) -> Stopping {
if let Some(start) = &self.start {
start();
}
Stopping(self.stop.clone())
}
}
pub(crate) struct Stopping(Option<Hook>);
impl Drop for Stopping {
fn drop(&mut self) {
if let Some(stop) = &self.0 {
stop();
}
}
}
impl core::fmt::Debug for ThreadHooks {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("ThreadHooks")
.field("start", &self.start.is_some())
.field("stop", &self.stop.is_some())
.field("park", &self.park.is_some())
.field("unpark", &self.unpark.is_some())
.finish()
}
}
#[derive(Debug)]
pub struct TaskMeta<'a> {
id: crate::task::Id,
_task: core::marker::PhantomData<&'a ()>,
}
impl TaskMeta<'_> {
pub(crate) fn new(id: crate::task::Id) -> Self {
Self {
id,
_task: core::marker::PhantomData,
}
}
pub fn id(&self) -> crate::task::Id {
self.id
}
}
pub(crate) type TaskHook = Arc<dyn Fn(&TaskMeta<'_>) + Send + Sync>;
#[derive(Clone, Default)]
pub(crate) struct TaskHooks {
pub(crate) spawn: Option<TaskHook>,
pub(crate) before_poll: Option<TaskHook>,
pub(crate) after_poll: Option<TaskHook>,
pub(crate) terminate: Option<TaskHook>,
pub(crate) shutdown: Option<std::sync::Weak<super::runtime::Inner>>,
}
impl TaskHooks {
pub(crate) fn any(&self) -> bool {
self.spawn.is_some()
|| self.before_poll.is_some()
|| self.after_poll.is_some()
|| self.terminate.is_some()
|| self.shutdown.is_some()
}
}
pub(crate) static ANY_TASK_HOOKS: core::sync::atomic::AtomicBool =
core::sync::atomic::AtomicBool::new(false);
pub(crate) static ANY_POLL_HOOKS: core::sync::atomic::AtomicBool =
core::sync::atomic::AtomicBool::new(false);
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[non_exhaustive]
pub enum UnhandledPanic {
#[default]
Ignore,
ShutdownRuntime,
}
pub(crate) fn call(hook: Option<&TaskHook>, id: crate::task::Id) {
if let Some(hook) = hook {
crate::rt::task::abort_on_panic(|| hook(&TaskMeta::new(id)));
}
}