use crate::core::{
rt::{TaskHandle, YieldData},
sync::{Arc, Condvar, Mutex},
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum Turn {
Scheduler(YieldData),
Task,
Poisoned,
}
pub(crate) struct ThreadTaskHandle {
cvar_pair: Arc<(Mutex<Turn>, Condvar)>,
}
impl ThreadTaskHandle {
pub(crate) fn new(cvar_pair: Arc<(Mutex<Turn>, Condvar)>) -> Self {
Self { cvar_pair }
}
}
impl TaskHandle for ThreadTaskHandle {
fn yield_now(&mut self, payload: YieldData) {
let mut state = self.cvar_pair.0.lock();
if *state == Turn::Poisoned {
drop(state);
panic!("Echeneis Internal Abort")
}
debug_assert_eq!(*state, Turn::Task);
*state = Turn::Scheduler(payload);
drop(state);
self.cvar_pair.1.notify_all();
let mut state = self.cvar_pair.0.lock();
state = self
.cvar_pair
.1
.wait_while(state, |state| !matches!(state, Turn::Task | Turn::Poisoned))
.unwrap();
if *state == Turn::Poisoned {
drop(state);
panic!("Echeneis Internal Abort");
}
}
}