executor: add spawner
This allows spawning a task on an executor from outside of it Fixes #1 Signed-off-by: Marc-Antoine Perennou <Marc-Antoine@Perennou.com>
This commit is contained in:
parent
c7bfd46e99
commit
b9c846ec47
81
src/lib.rs
81
src/lib.rs
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ scoped_thread_local!(static LOCAL_EX: LocalExecutor);
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Executor {
|
pub struct Executor {
|
||||||
ex: multitask::Executor,
|
ex: Arc<multitask::Executor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Executor {
|
impl Executor {
|
||||||
|
@ -81,13 +82,29 @@ impl Executor {
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use async_executor::LocalExecutor;
|
/// use async_executor::Executor;
|
||||||
///
|
///
|
||||||
/// let local_ex = LocalExecutor::new();
|
/// let ex = Executor::new();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn new() -> Executor {
|
pub fn new() -> Executor {
|
||||||
Executor {
|
Executor {
|
||||||
ex: multitask::Executor::new(),
|
ex: Arc::new(multitask::Executor::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a spawner for this executor.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use async_executor::Executor;
|
||||||
|
///
|
||||||
|
/// let ex = Executor::new();
|
||||||
|
/// let spawner = ex.spawner();
|
||||||
|
/// ```
|
||||||
|
pub fn spawner(&self) -> Spawner {
|
||||||
|
Spawner {
|
||||||
|
ex: self.ex.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +201,62 @@ impl Default for Executor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A spawner for a multi-threaded executor.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Spawner {
|
||||||
|
ex: Arc<multitask::Executor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Spawner {
|
||||||
|
/// Gets a spawner for the current multi-threaded executor.
|
||||||
|
///
|
||||||
|
/// If called from an [`Executor`], returns its [`Spawner`].
|
||||||
|
///
|
||||||
|
/// Otherwise, this method panics.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use async_executor::{Executor, Spawner};
|
||||||
|
///
|
||||||
|
/// let ex = Executor::new();
|
||||||
|
///
|
||||||
|
/// ex.run(async {
|
||||||
|
/// let spawner = Spawner::current();
|
||||||
|
/// let task = spawner.spawn(async { 1 + 2 });
|
||||||
|
/// assert_eq!(task.await, 3);
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
pub fn current() -> Spawner {
|
||||||
|
if EX.is_set() {
|
||||||
|
EX.with(|ex| ex.spawner())
|
||||||
|
} else {
|
||||||
|
panic!("`Spawner::current()` must be called from an `Executor`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Spawns a task onto the executor.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use async_executor::Executor;
|
||||||
|
///
|
||||||
|
/// let ex = Executor::new();
|
||||||
|
/// let spawner = ex.spawner();
|
||||||
|
///
|
||||||
|
/// let task = spawner.spawn(async {
|
||||||
|
/// println!("Hello world");
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
pub fn spawn<T: Send + 'static>(
|
||||||
|
&self,
|
||||||
|
future: impl Future<Output = T> + Send + 'static,
|
||||||
|
) -> Task<T> {
|
||||||
|
Task(self.ex.spawn(future))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Single-threaded executor.
|
/// Single-threaded executor.
|
||||||
///
|
///
|
||||||
/// The executor can only be run on the thread that created it.
|
/// The executor can only be run on the thread that created it.
|
||||||
|
|
Loading…
Reference in New Issue