summaryrefslogtreecommitdiffstats
path: root/third_party/rust/futures-util/src/task
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/futures-util/src/task')
-rw-r--r--third_party/rust/futures-util/src/task/mod.rs37
-rw-r--r--third_party/rust/futures-util/src/task/spawn.rs169
2 files changed, 206 insertions, 0 deletions
diff --git a/third_party/rust/futures-util/src/task/mod.rs b/third_party/rust/futures-util/src/task/mod.rs
new file mode 100644
index 0000000000..0a31eeac14
--- /dev/null
+++ b/third_party/rust/futures-util/src/task/mod.rs
@@ -0,0 +1,37 @@
+//! Tools for working with tasks.
+//!
+//! This module contains:
+//!
+//! - [`Spawn`], a trait for spawning new tasks.
+//! - [`Context`], a context of an asynchronous task,
+//! including a handle for waking up the task.
+//! - [`Waker`], a handle for waking up a task.
+//!
+//! The remaining types and traits in the module are used for implementing
+//! executors or dealing with synchronization issues around task wakeup.
+
+#[doc(no_inline)]
+pub use core::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
+
+pub use futures_task::{FutureObj, LocalFutureObj, LocalSpawn, Spawn, SpawnError, UnsafeFutureObj};
+
+pub use futures_task::noop_waker;
+pub use futures_task::noop_waker_ref;
+
+#[cfg(not(futures_no_atomic_cas))]
+#[cfg(feature = "alloc")]
+pub use futures_task::ArcWake;
+
+#[cfg(not(futures_no_atomic_cas))]
+#[cfg(feature = "alloc")]
+pub use futures_task::waker;
+
+#[cfg(not(futures_no_atomic_cas))]
+#[cfg(feature = "alloc")]
+pub use futures_task::{waker_ref, WakerRef};
+
+#[cfg(not(futures_no_atomic_cas))]
+pub use futures_core::task::__internal::AtomicWaker;
+
+mod spawn;
+pub use self::spawn::{LocalSpawnExt, SpawnExt};
diff --git a/third_party/rust/futures-util/src/task/spawn.rs b/third_party/rust/futures-util/src/task/spawn.rs
new file mode 100644
index 0000000000..d9e9985309
--- /dev/null
+++ b/third_party/rust/futures-util/src/task/spawn.rs
@@ -0,0 +1,169 @@
+use futures_task::{LocalSpawn, Spawn};
+
+#[cfg(feature = "compat")]
+use crate::compat::Compat;
+
+#[cfg(feature = "channel")]
+#[cfg(feature = "std")]
+use crate::future::{FutureExt, RemoteHandle};
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+#[cfg(feature = "alloc")]
+use futures_core::future::Future;
+#[cfg(feature = "alloc")]
+use futures_task::{FutureObj, LocalFutureObj, SpawnError};
+
+impl<Sp: ?Sized> SpawnExt for Sp where Sp: Spawn {}
+impl<Sp: ?Sized> LocalSpawnExt for Sp where Sp: LocalSpawn {}
+
+/// Extension trait for `Spawn`.
+pub trait SpawnExt: Spawn {
+ /// Spawns a task that polls the given future with output `()` to
+ /// completion.
+ ///
+ /// This method returns a [`Result`] that contains a [`SpawnError`] if
+ /// spawning fails.
+ ///
+ /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if
+ /// you want to spawn a future with output other than `()` or if you want
+ /// to be able to await its completion.
+ ///
+ /// Note this method will eventually be replaced with the upcoming
+ /// `Spawn::spawn` method which will take a `dyn Future` as input.
+ /// Technical limitations prevent `Spawn::spawn` from being implemented
+ /// today. Feel free to use this method in the meantime.
+ ///
+ /// ```
+ /// # {
+ /// use futures::executor::ThreadPool;
+ /// use futures::task::SpawnExt;
+ ///
+ /// let executor = ThreadPool::new().unwrap();
+ ///
+ /// let future = async { /* ... */ };
+ /// executor.spawn(future).unwrap();
+ /// # }
+ /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
+ /// ```
+ #[cfg(feature = "alloc")]
+ fn spawn<Fut>(&self, future: Fut) -> Result<(), SpawnError>
+ where
+ Fut: Future<Output = ()> + Send + 'static,
+ {
+ self.spawn_obj(FutureObj::new(Box::new(future)))
+ }
+
+ /// Spawns a task that polls the given future to completion and returns a
+ /// future that resolves to the spawned future's output.
+ ///
+ /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if
+ /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that
+ /// resolves to the output of the spawned future.
+ ///
+ /// ```
+ /// # {
+ /// use futures::executor::{block_on, ThreadPool};
+ /// use futures::future;
+ /// use futures::task::SpawnExt;
+ ///
+ /// let executor = ThreadPool::new().unwrap();
+ ///
+ /// let future = future::ready(1);
+ /// let join_handle_fut = executor.spawn_with_handle(future).unwrap();
+ /// assert_eq!(block_on(join_handle_fut), 1);
+ /// # }
+ /// # std::thread::sleep(std::time::Duration::from_millis(500)); // wait for background threads closed: https://github.com/rust-lang/miri/issues/1371
+ /// ```
+ #[cfg(feature = "channel")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
+ #[cfg(feature = "std")]
+ fn spawn_with_handle<Fut>(&self, future: Fut) -> Result<RemoteHandle<Fut::Output>, SpawnError>
+ where
+ Fut: Future + Send + 'static,
+ Fut::Output: Send,
+ {
+ let (future, handle) = future.remote_handle();
+ self.spawn(future)?;
+ Ok(handle)
+ }
+
+ /// Wraps a [`Spawn`] and makes it usable as a futures 0.1 `Executor`.
+ /// Requires the `compat` feature to enable.
+ #[cfg(feature = "compat")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "compat")))]
+ fn compat(self) -> Compat<Self>
+ where
+ Self: Sized,
+ {
+ Compat::new(self)
+ }
+}
+
+/// Extension trait for `LocalSpawn`.
+pub trait LocalSpawnExt: LocalSpawn {
+ /// Spawns a task that polls the given future with output `()` to
+ /// completion.
+ ///
+ /// This method returns a [`Result`] that contains a [`SpawnError`] if
+ /// spawning fails.
+ ///
+ /// You can use [`spawn_with_handle`](SpawnExt::spawn_with_handle) if
+ /// you want to spawn a future with output other than `()` or if you want
+ /// to be able to await its completion.
+ ///
+ /// Note this method will eventually be replaced with the upcoming
+ /// `Spawn::spawn` method which will take a `dyn Future` as input.
+ /// Technical limitations prevent `Spawn::spawn` from being implemented
+ /// today. Feel free to use this method in the meantime.
+ ///
+ /// ```
+ /// use futures::executor::LocalPool;
+ /// use futures::task::LocalSpawnExt;
+ ///
+ /// let executor = LocalPool::new();
+ /// let spawner = executor.spawner();
+ ///
+ /// let future = async { /* ... */ };
+ /// spawner.spawn_local(future).unwrap();
+ /// ```
+ #[cfg(feature = "alloc")]
+ fn spawn_local<Fut>(&self, future: Fut) -> Result<(), SpawnError>
+ where
+ Fut: Future<Output = ()> + 'static,
+ {
+ self.spawn_local_obj(LocalFutureObj::new(Box::new(future)))
+ }
+
+ /// Spawns a task that polls the given future to completion and returns a
+ /// future that resolves to the spawned future's output.
+ ///
+ /// This method returns a [`Result`] that contains a [`RemoteHandle`](crate::future::RemoteHandle), or, if
+ /// spawning fails, a [`SpawnError`]. [`RemoteHandle`](crate::future::RemoteHandle) is a future that
+ /// resolves to the output of the spawned future.
+ ///
+ /// ```
+ /// use futures::executor::LocalPool;
+ /// use futures::task::LocalSpawnExt;
+ ///
+ /// let mut executor = LocalPool::new();
+ /// let spawner = executor.spawner();
+ ///
+ /// let future = async { 1 };
+ /// let join_handle_fut = spawner.spawn_local_with_handle(future).unwrap();
+ /// assert_eq!(executor.run_until(join_handle_fut), 1);
+ /// ```
+ #[cfg(feature = "channel")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "channel")))]
+ #[cfg(feature = "std")]
+ fn spawn_local_with_handle<Fut>(
+ &self,
+ future: Fut,
+ ) -> Result<RemoteHandle<Fut::Output>, SpawnError>
+ where
+ Fut: Future + 'static,
+ {
+ let (future, handle) = future.remote_handle();
+ self.spawn_local(future)?;
+ Ok(handle)
+ }
+}