use std::mem;
use super::{RustFutureContinuationCallback, RustFuturePoll};
#[derive(Debug)]
pub(super) enum Scheduler {
Empty,
Waked,
Cancelled,
Set(RustFutureContinuationCallback, u64),
}
impl Scheduler {
pub(super) fn new() -> Self {
Self::Empty
}
pub(super) fn store(&mut self, callback: RustFutureContinuationCallback, data: u64) {
match self {
Self::Empty => *self = Self::Set(callback, data),
Self::Set(old_callback, old_data) => {
trace!(
"store: observed `Self::Set` state. Is poll() being called from multiple threads at once?"
);
old_callback(*old_data, RustFuturePoll::Ready);
*self = Self::Set(callback, data);
}
Self::Waked => {
*self = Self::Empty;
callback(data, RustFuturePoll::Wake);
}
Self::Cancelled => {
callback(data, RustFuturePoll::Ready);
}
}
}
pub(super) fn wake(&mut self) {
match self {
Self::Set(callback, old_data) => {
let old_data = *old_data;
let callback = *callback;
*self = Self::Empty;
callback(old_data, RustFuturePoll::Wake);
}
Self::Empty => *self = Self::Waked,
_ => (),
}
}
pub(super) fn cancel(&mut self) {
if let Self::Set(callback, old_data) = mem::replace(self, Self::Cancelled) {
callback(old_data, RustFuturePoll::Ready);
}
}
pub(super) fn is_cancelled(&self) -> bool {
matches!(self, Self::Cancelled)
}
}
unsafe impl Send for Scheduler {}
unsafe impl Sync for Scheduler {}