use crate::runtime::compat;
use crate::runtime::current_thread::Runtime;
use std::{
io,
sync::{Arc, RwLock},
};
use tokio_02::runtime;
use tokio_timer_02::clock::Clock;
#[derive(Debug)]
#[cfg_attr(docsrs, doc(cfg(feature = "rt-current-thread")))]
pub struct Builder {
clock: Clock,
inner: runtime::Builder,
}
impl Builder {
pub fn new() -> Builder {
Builder {
clock: Clock::system(),
inner: runtime::Builder::new(),
}
}
pub fn clock(&mut self, clock: Clock) -> &mut Self {
self.clock = clock;
self
}
pub fn build(&mut self) -> io::Result<Runtime> {
let compat_bg = compat::Background::spawn(&self.clock)?;
let compat_timer = compat_bg.timer().clone();
let compat_reactor = compat_bg.reactor().clone();
let compat_sender: Arc<RwLock<Option<compat::CompatSpawner<tokio_02::runtime::Handle>>>> =
Arc::new(RwLock::new(None));
let compat_sender2 = compat_sender.clone();
let mut lock = compat_sender.write().unwrap();
let runtime = self
.inner
.basic_scheduler()
.enable_all()
.on_thread_start(move || {
let lock = compat_sender2.read().unwrap();
let compat_sender = lock
.as_ref()
.expect("compat executor needs to be set before runtime is run!")
.clone();
compat::set_guards(compat_sender, &compat_timer, &compat_reactor);
})
.on_thread_stop(|| {
compat::unset_guards();
})
.build()?;
let (idle, idle_rx) = super::idle::Idle::new();
*lock = Some(compat::CompatSpawner::new(runtime.handle().clone(), &idle));
drop(lock);
Ok(Runtime::new2(runtime, idle, idle_rx, compat_bg))
}
}
impl Default for Builder {
fn default() -> Self {
Self::new()
}
}