diff options
Diffstat (limited to 'src/task/builder.rs')
-rw-r--r-- | src/task/builder.rs | 131 |
1 files changed, 115 insertions, 16 deletions
diff --git a/src/task/builder.rs b/src/task/builder.rs index f991fc6..91c400c 100644 --- a/src/task/builder.rs +++ b/src/task/builder.rs @@ -1,9 +1,16 @@ #![allow(unreachable_pub)] -use crate::{runtime::context, task::JoinHandle}; -use std::future::Future; +use crate::{ + runtime::Handle, + task::{JoinHandle, LocalSet}, +}; +use std::{future::Future, io}; /// Factory which is used to configure the properties of a new task. /// +/// **Note**: This is an [unstable API][unstable]. The public API of this type +/// may break in 1.x releases. See [the documentation on unstable +/// features][unstable] for details. +/// /// Methods can be chained in order to configure it. /// /// Currently, there is only one configuration option: @@ -41,11 +48,17 @@ use std::future::Future; /// .spawn(async move { /// // Process each socket concurrently. /// process(socket).await -/// }); +/// })?; /// } /// } /// ``` +/// [unstable]: crate#unstable-features +/// [`name`]: Builder::name +/// [`spawn_local`]: Builder::spawn_local +/// [`spawn`]: Builder::spawn +/// [`spawn_blocking`]: Builder::spawn_blocking #[derive(Default, Debug)] +#[cfg_attr(docsrs, doc(cfg(all(tokio_unstable, feature = "tracing"))))] pub struct Builder<'a> { name: Option<&'a str>, } @@ -61,42 +74,128 @@ impl<'a> Builder<'a> { Self { name: Some(name) } } - /// Spawns a task on the executor. + /// Spawns a task with this builder's settings on the current runtime. + /// + /// # Panics + /// + /// This method panics if called outside of a Tokio runtime. /// /// See [`task::spawn`](crate::task::spawn) for /// more details. - #[cfg_attr(tokio_track_caller, track_caller)] - pub fn spawn<Fut>(self, future: Fut) -> JoinHandle<Fut::Output> + #[track_caller] + pub fn spawn<Fut>(self, future: Fut) -> io::Result<JoinHandle<Fut::Output>> where Fut: Future + Send + 'static, Fut::Output: Send + 'static, { - super::spawn::spawn_inner(future, self.name) + Ok(super::spawn::spawn_inner(future, self.name)) } - /// Spawns a task on the current thread. + /// Spawn a task with this builder's settings on the provided [runtime + /// handle]. /// - /// See [`task::spawn_local`](crate::task::spawn_local) - /// for more details. - #[cfg_attr(tokio_track_caller, track_caller)] - pub fn spawn_local<Fut>(self, future: Fut) -> JoinHandle<Fut::Output> + /// See [`Handle::spawn`] for more details. + /// + /// [runtime handle]: crate::runtime::Handle + /// [`Handle::spawn`]: crate::runtime::Handle::spawn + #[track_caller] + pub fn spawn_on<Fut>(self, future: Fut, handle: &Handle) -> io::Result<JoinHandle<Fut::Output>> + where + Fut: Future + Send + 'static, + Fut::Output: Send + 'static, + { + Ok(handle.spawn_named(future, self.name)) + } + + /// Spawns `!Send` a task on the current [`LocalSet`] with this builder's + /// settings. + /// + /// The spawned future will be run on the same thread that called `spawn_local`. + /// This may only be called from the context of a [local task set][`LocalSet`]. + /// + /// # Panics + /// + /// This function panics if called outside of a [local task set][`LocalSet`]. + /// + /// See [`task::spawn_local`] for more details. + /// + /// [`task::spawn_local`]: crate::task::spawn_local + /// [`LocalSet`]: crate::task::LocalSet + #[track_caller] + pub fn spawn_local<Fut>(self, future: Fut) -> io::Result<JoinHandle<Fut::Output>> where Fut: Future + 'static, Fut::Output: 'static, { - super::local::spawn_local_inner(future, self.name) + Ok(super::local::spawn_local_inner(future, self.name)) + } + + /// Spawns `!Send` a task on the provided [`LocalSet`] with this builder's + /// settings. + /// + /// See [`LocalSet::spawn_local`] for more details. + /// + /// [`LocalSet::spawn_local`]: crate::task::LocalSet::spawn_local + /// [`LocalSet`]: crate::task::LocalSet + #[track_caller] + pub fn spawn_local_on<Fut>( + self, + future: Fut, + local_set: &LocalSet, + ) -> io::Result<JoinHandle<Fut::Output>> + where + Fut: Future + 'static, + Fut::Output: 'static, + { + Ok(local_set.spawn_named(future, self.name)) } /// Spawns blocking code on the blocking threadpool. /// + /// # Panics + /// + /// This method panics if called outside of a Tokio runtime. + /// /// See [`task::spawn_blocking`](crate::task::spawn_blocking) /// for more details. - #[cfg_attr(tokio_track_caller, track_caller)] - pub fn spawn_blocking<Function, Output>(self, function: Function) -> JoinHandle<Output> + #[track_caller] + pub fn spawn_blocking<Function, Output>( + self, + function: Function, + ) -> io::Result<JoinHandle<Output>> where Function: FnOnce() -> Output + Send + 'static, Output: Send + 'static, { - context::current().spawn_blocking_inner(function, self.name) + let handle = Handle::current(); + self.spawn_blocking_on(function, &handle) + } + + /// Spawns blocking code on the provided [runtime handle]'s blocking threadpool. + /// + /// See [`Handle::spawn_blocking`] for more details. + /// + /// [runtime handle]: crate::runtime::Handle + /// [`Handle::spawn_blocking`]: crate::runtime::Handle::spawn_blocking + #[track_caller] + pub fn spawn_blocking_on<Function, Output>( + self, + function: Function, + handle: &Handle, + ) -> io::Result<JoinHandle<Output>> + where + Function: FnOnce() -> Output + Send + 'static, + Output: Send + 'static, + { + use crate::runtime::Mandatory; + let (join_handle, spawn_result) = handle.inner.blocking_spawner().spawn_blocking_inner( + function, + Mandatory::NonMandatory, + self.name, + handle, + ); + + spawn_result?; + Ok(join_handle) } } |