use std::thread;
use crate::coroutine_impl::{current_cancel_data, is_coroutine};
use crate::coroutine_impl::{CoroutineImpl, EventResult, EventSource, EventSubscriber};
use crate::scheduler::get_scheduler;
use mco_gen::{co_get_yield, co_set_para, co_yield_with};
struct Yield {}
impl EventSource for Yield {
fn subscribe(&mut self, co: CoroutineImpl) {
get_scheduler().schedule(co);
}
}
#[inline]
pub fn yield_with<T: EventSource>(resource: &T) {
let cancel = current_cancel_data();
if cancel.is_canceled() {
{
co_set_para(::std::io::Error::new(
::std::io::ErrorKind::Other,
"Canceled",
));
return resource.yield_back(cancel);
}
}
let r = resource as &dyn EventSource as *const _ as *mut _;
let es = EventSubscriber::new(r);
co_yield_with(es);
resource.yield_back(cancel);
cancel.clear();
}
#[inline]
pub fn set_co_para(co: &mut CoroutineImpl, v: EventResult) {
co.set_para(v);
}
#[inline]
pub fn get_co_para() -> Option<EventResult> {
co_get_yield::<EventResult>()
}
#[inline]
pub fn yield_now() {
if !is_coroutine() {
return thread::yield_now();
}
let y = Yield {};
yield_with(&y);
}