use crate::sync::AtomicOption;
use std::sync::Arc;
use std::thread;
use std::time::Duration;
use crate::coroutine_impl::{co_cancel_data, is_coroutine, CoroutineImpl, EventSource};
use crate::likely::unlikely;
use crate::scheduler::get_scheduler;
use crate::yield_now::{get_co_para, yield_with};
struct Sleep {
dur: Duration,
}
impl EventSource for Sleep {
fn subscribe(&mut self, co: CoroutineImpl) {
let cancel = co_cancel_data(&co);
let sleep_co = Arc::new(AtomicOption::some(co));
get_scheduler().add_timer(self.dur, sleep_co.clone());
cancel.set_co(sleep_co);
if cancel.is_canceled() {
unsafe { cancel.cancel() };
}
}
}
pub fn sleep(dur: Duration) {
if unlikely(!is_coroutine()) {
return thread::sleep(dur);
}
let sleeper = Sleep { dur };
yield_with(&sleeper);
get_co_para();
}