Created
August 15, 2019 16:03
-
-
Save DoumanAsh/1c6e0d6198d02ab242ad148fd4c4bd4f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///Describes Executor configuration | |
pub trait ExecutorConfig { | |
///Function to call when exectur goes to sleep. | |
fn on_sleep(&mut self) { | |
#[cfg(not(feature = "std"))] | |
core::sync::atomic::spin_loop_hint(); | |
#[cfg(feature = "std")] | |
std::thread::yield_now(); | |
} | |
///Function to perform poll of future. | |
fn poll_block<R, F: FnOnce() -> R>(&self, poll: F) -> R { | |
poll() | |
} | |
///Function to be called when `Executor` is woken. | |
/// | |
///Does nothing by default | |
fn wake() { | |
} | |
} | |
///Default configuration | |
/// | |
///By default it uses following `ON_SLEEP`: | |
/// | |
///`no_std` - `core::sync::atomic::spin_loop_hint` | |
///`std` - `std::thread::yield_now` | |
pub struct DefaultCfg; | |
impl ExecutorConfig for DefaultCfg {} | |
///Trivial single threaded executor than can only run single future. | |
pub struct Executor<C=DefaultCfg> where C: ExecutorConfig { | |
config: C, | |
waker: MehishaWaker, | |
} | |
impl Executor { | |
///Creates Executor with [Default Config](struct.DefaultCfg.html). | |
pub const fn with_default() -> Self { | |
Self::new(DefaultCfg) | |
} | |
} | |
impl<C: ExecutorConfig> Executor<C> { | |
///Creates Executor with provided configuration. | |
pub const fn new(config: C) -> Self { | |
Self { | |
config, | |
waker: MehishaWaker::new(C::wake), | |
} | |
} | |
} | |
impl<C: ExecutorConfig> super::Executor for Executor<C> { | |
fn run<F: Future>(&mut self, mut future: F) -> F::Output { | |
let waker = self.waker.waker(); | |
let mut context = task::Context::from_waker(&waker); | |
loop { | |
let poll = self.config.poll_block(|| Future::poll(unsafe { Pin::new_unchecked(&mut future) }, &mut context)); | |
match poll { | |
task::Poll::Ready(result) => break result, | |
task::Poll::Pending => while !self.waker.take_woke_status() { | |
self.config.on_sleep(); | |
} | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct Config { | |
reactor: tokio::reactor::Reactor, | |
} | |
impl Config { | |
fn new() -> Self { | |
Self { | |
reactor: tokio::reactor::Reactor::new().expect("To create tokio reactor"), | |
} | |
} | |
} | |
impl ExecutorConfig for Config { | |
fn poll_block<R, F: FnOnce() -> R>(&self, poll: F) -> R { | |
tokio_reactor::with_default(&self.reactor.handle(), poll) | |
} | |
fn on_sleep(&mut self) { | |
match self.reactor.is_idle() { | |
true => (), | |
false => { | |
self.reactor.turn(None).expect("To turn reactor"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment