use std::cell::Cell;
use super::{ProcessId, SchedulerOps, SpawnSpec};
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ThreadEvent {
Start {
pid: ProcessId,
parent: Option<ProcessId>,
spawn: Option<SpawnSpec>,
},
Enter { pid: ProcessId },
End { pid: ProcessId, killed: bool },
}
pub type ThreadHook = fn(&dyn SchedulerOps, ThreadEvent);
thread_local! {
static HOOK: Cell<Option<ThreadHook>> = const { Cell::new(None) };
}
pub fn set_thread_hook(hook: Option<ThreadHook>) {
HOOK.with(|h| h.set(hook));
}
#[inline]
pub fn thread_hook_installed() -> bool {
HOOK.with(|h| h.get().is_some())
}
pub fn fire_thread_event(ops: &dyn SchedulerOps, event: ThreadEvent) {
if let Some(hook) = HOOK.with(Cell::get) {
let pid = match event {
ThreadEvent::Start { pid, .. }
| ThreadEvent::Enter { pid }
| ThreadEvent::End { pid, .. } => pid,
};
super::with_scheduler_ops(ops, || {
super::with_current_process(pid, || hook(ops, event));
});
}
}