1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
//! A batteries included runtime for applications using mobc.
//! Mobc does not implement runtime, it simply exports runtime.
pub use runtime::{DefaultExecutor, Runtime, TaskExecutor};
use std::future::Future;
use std::pin::Pin;
// A new type exports the default executor of Tokio..
// pub type DefaultExecutor = DefaultExecutor;
/// A value that executes futures.
/// see [tokio::Executor](https://docs.rs/tokio/0.2.0-alpha.6/tokio/executor/trait.Executor.html)
pub trait Executor: Send + Sync + 'static + Clone {
/// Spawns a future object to run on this executor.
///
/// `future` is passed to the executor, which will begin running it. The
/// future may run on the current thread or another thread at the discretion
/// of the `Executor` implementation.
fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>);
}
#[cfg(all(feature = "tokio", not(feature = "async-std")))]
mod runtime {
use super::*;
/// Wrapper of the Tokio Runtime
pub struct Runtime {
rt: tokio::runtime::Runtime,
spawner: TaskExecutor,
}
impl Runtime {
/// Creates a new Runtime
pub fn new() -> Option<Self> {
Some(Runtime {
rt: tokio::runtime::Runtime::new().unwrap(),
spawner: TaskExecutor,
})
}
/// Returns a spawner
pub fn handle(&self) -> &TaskExecutor {
&self.spawner
}
/// Run a future to completion on the Tokio runtime. This is the
/// runtime's entry point.
pub fn block_on<F, T>(&mut self, future: F) -> T
where
F: Future<Output = T>,
{
self.rt.block_on(future)
}
/// Spawn a future onto the Tokio runtime.
pub fn spawn<F, T>(&self, future: F)
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
self.rt.spawn(future);
}
}
/// Simple handler for spawning task
#[derive(Clone)]
pub struct TaskExecutor;
impl TaskExecutor {
/// Spawn a future onto the Tokio runtime.
pub fn spawn<F>(&self, future: F)
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
tokio::spawn(future);
}
}
#[derive(Clone)]
/// The default executor of tokio.
pub struct DefaultExecutor;
impl DefaultExecutor {
/// The default executor of tokio.
pub fn current() -> Self {
Self {}
}
}
impl Executor for DefaultExecutor {
fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
tokio::spawn(future);
}
}
}
#[cfg(all(feature = "async-std"))]
mod runtime {
use super::*;
use async_std::task;
#[derive(Clone)]
pub struct TaskExecutor;
impl TaskExecutor {
pub fn spawn<F>(&self, future: F)
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
task::spawn(future);
}
}
pub struct Runtime(TaskExecutor);
impl Runtime {
pub fn new() -> Option<Self> {
Some(Runtime(TaskExecutor))
}
pub fn handle(&self) -> &TaskExecutor {
&self.0
}
pub fn block_on<F, T>(&mut self, future: F) -> T
where
F: Future<Output = T>,
{
task::block_on(future)
}
pub fn spawn<F, T>(&self, future: F)
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
task::spawn(future);
}
}
#[derive(Clone)]
pub struct DefaultExecutor;
impl DefaultExecutor {
pub fn current() -> Self {
Self {}
}
}
impl Executor for DefaultExecutor {
fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) {
task::spawn(future);
}
}
}