diff --git a/tokio-executor/Cargo.toml b/tokio-executor/Cargo.toml index f9089b1e5..de25bbce4 100644 --- a/tokio-executor/Cargo.toml +++ b/tokio-executor/Cargo.toml @@ -29,7 +29,6 @@ threadpool = [ "crossbeam-queue", "crossbeam-utils", "futures-core-preview", - "futures-util-preview", "num_cpus", "lazy_static", "slab", @@ -39,6 +38,7 @@ threadpool = [ tokio-sync = { version = "=0.2.0-alpha.2", optional = true, path = "../tokio-sync" } tracing = { version = "0.1.5", optional = true } +futures-util-preview = { version = "=0.3.0-alpha.18", features = ["channel"] } # current-thread dependencies crossbeam-channel = { version = "0.3.8", optional = true } @@ -48,7 +48,6 @@ crossbeam-deque = { version = "0.7.0", optional = true } crossbeam-queue = { version = "0.1.0", optional = true } crossbeam-utils = { version = "0.6.4", optional = true } futures-core-preview = { version = "=0.3.0-alpha.18", optional = true } -futures-util-preview = { version = "=0.3.0-alpha.18", optional = true } num_cpus = { version = "1.2", optional = true } lazy_static = { version = "1", optional = true } slab = { version = "0.4.1", optional = true } diff --git a/tokio-executor/src/executor.rs b/tokio-executor/src/executor.rs index 3ca07f5f2..3df6bbc23 100644 --- a/tokio-executor/src/executor.rs +++ b/tokio-executor/src/executor.rs @@ -1,4 +1,5 @@ use crate::SpawnError; +use futures_util::future::{FutureExt, RemoteHandle}; use std::future::Future; use std::pin::Pin; @@ -123,6 +124,48 @@ pub trait Executor { } } +impl dyn Executor { + /// Spawns a future object to run on this executor, returning a result of + /// its `RemoteHandle`. + /// + /// `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. + /// + /// # Panics + /// + /// Implementations are encouraged to avoid panics. However, panics are + /// permitted and the caller should check the implementation specific + /// documentation for more details on possible panics. + /// + /// # Examples + /// + /// ``` + /// use tokio_executor::Executor; + /// use futures_util::future::FutureExt; + /// + /// # fn docs(my_executor: &'static mut (dyn Executor + 'static)) { + /// let handle = my_executor.spawn_with_handle(Box::pin(async { + /// println!("running on the executor"); + /// })).unwrap(); + /// + /// handle.map(|_| println!("the future has completed")); + /// # } + /// ``` + pub fn spawn_with_handle( + &mut self, + future: Fut, + ) -> Result, SpawnError> + where + Fut: Future + Send + 'static, + Fut::Output: Send, + { + let (future, handle) = future.remote_handle(); + self.spawn(Box::pin(future))?; + Ok(handle) + } +} + impl Executor for Box { fn spawn( &mut self, diff --git a/tokio-executor/src/lib.rs b/tokio-executor/src/lib.rs index bfdd0fe62..906d86890 100644 --- a/tokio-executor/src/lib.rs +++ b/tokio-executor/src/lib.rs @@ -81,3 +81,4 @@ pub use crate::error::SpawnError; pub use crate::executor::Executor; pub use crate::global::{spawn, with_default, DefaultExecutor}; pub use crate::typed::TypedExecutor; +pub use futures_util::future::RemoteHandle;