diff options
Diffstat (limited to 'src/libcore/task')
| -rw-r--r-- | src/libcore/task/mod.rs | 15 | ||||
| -rw-r--r-- | src/libcore/task/poll.rs | 167 | ||||
| -rw-r--r-- | src/libcore/task/ready.rs | 60 | ||||
| -rw-r--r-- | src/libcore/task/wake.rs | 320 |
4 files changed, 0 insertions, 562 deletions
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs deleted file mode 100644 index 3d6f4f5971a..00000000000 --- a/src/libcore/task/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -#![stable(feature = "futures_api", since = "1.36.0")] - -//! Types and Traits for working with asynchronous tasks. - -mod poll; -#[stable(feature = "futures_api", since = "1.36.0")] -pub use self::poll::Poll; - -mod wake; -#[stable(feature = "futures_api", since = "1.36.0")] -pub use self::wake::{Context, RawWaker, RawWakerVTable, Waker}; - -mod ready; -#[unstable(feature = "ready_macro", issue = "70922")] -pub use ready::ready; diff --git a/src/libcore/task/poll.rs b/src/libcore/task/poll.rs deleted file mode 100644 index b3a4bd20b8f..00000000000 --- a/src/libcore/task/poll.rs +++ /dev/null @@ -1,167 +0,0 @@ -#![stable(feature = "futures_api", since = "1.36.0")] - -use crate::ops::Try; -use crate::result::Result; - -/// Indicates whether a value is available or if the current task has been -/// scheduled to receive a wakeup instead. -#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"] -#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[stable(feature = "futures_api", since = "1.36.0")] -pub enum Poll<T> { - /// Represents that a value is immediately ready. - #[stable(feature = "futures_api", since = "1.36.0")] - Ready(#[stable(feature = "futures_api", since = "1.36.0")] T), - - /// Represents that a value is not ready yet. - /// - /// When a function returns `Pending`, the function *must* also - /// ensure that the current task is scheduled to be awoken when - /// progress can be made. - #[stable(feature = "futures_api", since = "1.36.0")] - Pending, -} - -impl<T> Poll<T> { - /// Changes the ready value of this `Poll` with the closure provided. - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn map<U, F>(self, f: F) -> Poll<U> - where - F: FnOnce(T) -> U, - { - match self { - Poll::Ready(t) => Poll::Ready(f(t)), - Poll::Pending => Poll::Pending, - } - } - - /// Returns `true` if this is `Poll::Ready` - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_ready(&self) -> bool { - matches!(*self, Poll::Ready(_)) - } - - /// Returns `true` if this is `Poll::Pending` - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn is_pending(&self) -> bool { - !self.is_ready() - } -} - -impl<T, E> Poll<Result<T, E>> { - /// Changes the success value of this `Poll` with the closure provided. - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>> - where - F: FnOnce(T) -> U, - { - match self { - Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))), - Poll::Ready(Err(e)) => Poll::Ready(Err(e)), - Poll::Pending => Poll::Pending, - } - } - - /// Changes the error value of this `Poll` with the closure provided. - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>> - where - F: FnOnce(E) -> U, - { - match self { - Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)), - Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))), - Poll::Pending => Poll::Pending, - } - } -} - -impl<T, E> Poll<Option<Result<T, E>>> { - /// Changes the success value of this `Poll` with the closure provided. - #[unstable(feature = "poll_map", issue = "63514")] - pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>> - where - F: FnOnce(T) -> U, - { - match self { - Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))), - Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))), - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => Poll::Pending, - } - } - - /// Changes the error value of this `Poll` with the closure provided. - #[unstable(feature = "poll_map", issue = "63514")] - pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>> - where - F: FnOnce(E) -> U, - { - match self { - Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))), - Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))), - Poll::Ready(None) => Poll::Ready(None), - Poll::Pending => Poll::Pending, - } - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl<T> From<T> for Poll<T> { - fn from(t: T) -> Poll<T> { - Poll::Ready(t) - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl<T, E> Try for Poll<Result<T, E>> { - type Ok = Poll<T>; - type Error = E; - - #[inline] - fn into_result(self) -> Result<Self::Ok, Self::Error> { - match self { - Poll::Ready(Ok(x)) => Ok(Poll::Ready(x)), - Poll::Ready(Err(e)) => Err(e), - Poll::Pending => Ok(Poll::Pending), - } - } - - #[inline] - fn from_error(e: Self::Error) -> Self { - Poll::Ready(Err(e)) - } - - #[inline] - fn from_ok(x: Self::Ok) -> Self { - x.map(Ok) - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl<T, E> Try for Poll<Option<Result<T, E>>> { - type Ok = Poll<Option<T>>; - type Error = E; - - #[inline] - fn into_result(self) -> Result<Self::Ok, Self::Error> { - match self { - Poll::Ready(Some(Ok(x))) => Ok(Poll::Ready(Some(x))), - Poll::Ready(Some(Err(e))) => Err(e), - Poll::Ready(None) => Ok(Poll::Ready(None)), - Poll::Pending => Ok(Poll::Pending), - } - } - - #[inline] - fn from_error(e: Self::Error) -> Self { - Poll::Ready(Some(Err(e))) - } - - #[inline] - fn from_ok(x: Self::Ok) -> Self { - x.map(|x| x.map(Ok)) - } -} diff --git a/src/libcore/task/ready.rs b/src/libcore/task/ready.rs deleted file mode 100644 index d4e733eb2bc..00000000000 --- a/src/libcore/task/ready.rs +++ /dev/null @@ -1,60 +0,0 @@ -/// Extracts the successful type of a `Poll<T>`. -/// -/// This macro bakes in propagation of `Pending` signals by returning early. -/// -/// # Examples -/// -/// ``` -/// #![feature(future_readiness_fns)] -/// #![feature(ready_macro)] -/// -/// use core::task::{ready, Context, Poll}; -/// use core::future::{self, Future}; -/// use core::pin::Pin; -/// -/// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> { -/// let mut fut = future::ready(42); -/// let fut = Pin::new(&mut fut); -/// -/// let num = ready!(fut.poll(cx)); -/// # drop(num); -/// // ... use num -/// -/// Poll::Ready(()) -/// } -/// ``` -/// -/// The `ready!` call expands to: -/// -/// ``` -/// # #![feature(future_readiness_fns)] -/// # #![feature(ready_macro)] -/// # -/// # use core::task::{Context, Poll}; -/// # use core::future::{self, Future}; -/// # use core::pin::Pin; -/// # -/// # pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> { -/// # let mut fut = future::ready(42); -/// # let fut = Pin::new(&mut fut); -/// # -/// let num = match fut.poll(cx) { -/// Poll::Ready(t) => t, -/// Poll::Pending => return Poll::Pending, -/// }; -/// # drop(num); -/// # // ... use num -/// # -/// # Poll::Ready(()) -/// # } -/// ``` -#[unstable(feature = "ready_macro", issue = "70922")] -#[rustc_macro_transparency = "semitransparent"] -pub macro ready($e:expr) { - match $e { - $crate::task::Poll::Ready(t) => t, - $crate::task::Poll::Pending => { - return $crate::task::Poll::Pending; - } - } -} diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs deleted file mode 100644 index b070b665b4d..00000000000 --- a/src/libcore/task/wake.rs +++ /dev/null @@ -1,320 +0,0 @@ -#![stable(feature = "futures_api", since = "1.36.0")] - -use crate::fmt; -use crate::marker::{PhantomData, Unpin}; - -/// A `RawWaker` allows the implementor of a task executor to create a [`Waker`] -/// which provides customized wakeup behavior. -/// -/// [vtable]: https://en.wikipedia.org/wiki/Virtual_method_table -/// -/// It consists of a data pointer and a [virtual function pointer table (vtable)][vtable] that -/// customizes the behavior of the `RawWaker`. -/// -/// [`Waker`]: struct.Waker.html -#[derive(PartialEq, Debug)] -#[stable(feature = "futures_api", since = "1.36.0")] -pub struct RawWaker { - /// A data pointer, which can be used to store arbitrary data as required - /// by the executor. This could be e.g. a type-erased pointer to an `Arc` - /// that is associated with the task. - /// The value of this field gets passed to all functions that are part of - /// the vtable as the first parameter. - data: *const (), - /// Virtual function pointer table that customizes the behavior of this waker. - vtable: &'static RawWakerVTable, -} - -impl RawWaker { - /// Creates a new `RawWaker` from the provided `data` pointer and `vtable`. - /// - /// The `data` pointer can be used to store arbitrary data as required - /// by the executor. This could be e.g. a type-erased pointer to an `Arc` - /// that is associated with the task. - /// The value of this pointer will get passed to all functions that are part - /// of the `vtable` as the first parameter. - /// - /// The `vtable` customizes the behavior of a `Waker` which gets created - /// from a `RawWaker`. For each operation on the `Waker`, the associated - /// function in the `vtable` of the underlying `RawWaker` will be called. - #[rustc_promotable] - #[stable(feature = "futures_api", since = "1.36.0")] - #[rustc_const_stable(feature = "futures_api", since = "1.36.0")] - pub const fn new(data: *const (), vtable: &'static RawWakerVTable) -> RawWaker { - RawWaker { data, vtable } - } -} - -/// A virtual function pointer table (vtable) that specifies the behavior -/// of a [`RawWaker`]. -/// -/// The pointer passed to all functions inside the vtable is the `data` pointer -/// from the enclosing [`RawWaker`] object. -/// -/// The functions inside this struct are only intended be called on the `data` -/// pointer of a properly constructed [`RawWaker`] object from inside the -/// [`RawWaker`] implementation. Calling one of the contained functions using -/// any other `data` pointer will cause undefined behavior. -/// -/// [`RawWaker`]: struct.RawWaker.html -#[stable(feature = "futures_api", since = "1.36.0")] -#[derive(PartialEq, Copy, Clone, Debug)] -pub struct RawWakerVTable { - /// This function will be called when the [`RawWaker`] gets cloned, e.g. when - /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned. - /// - /// The implementation of this function must retain all resources that are - /// required for this additional instance of a [`RawWaker`] and associated - /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup - /// of the same task that would have been awoken by the original [`RawWaker`]. - /// - /// [`Waker`]: struct.Waker.html - /// [`RawWaker`]: struct.RawWaker.html - clone: unsafe fn(*const ()) -> RawWaker, - - /// This function will be called when `wake` is called on the [`Waker`]. - /// It must wake up the task associated with this [`RawWaker`]. - /// - /// The implementation of this function must make sure to release any - /// resources that are associated with this instance of a [`RawWaker`] and - /// associated task. - /// - /// [`Waker`]: struct.Waker.html - /// [`RawWaker`]: struct.RawWaker.html - wake: unsafe fn(*const ()), - - /// This function will be called when `wake_by_ref` is called on the [`Waker`]. - /// It must wake up the task associated with this [`RawWaker`]. - /// - /// This function is similar to `wake`, but must not consume the provided data - /// pointer. - /// - /// [`Waker`]: struct.Waker.html - /// [`RawWaker`]: struct.RawWaker.html - wake_by_ref: unsafe fn(*const ()), - - /// This function gets called when a [`RawWaker`] gets dropped. - /// - /// The implementation of this function must make sure to release any - /// resources that are associated with this instance of a [`RawWaker`] and - /// associated task. - /// - /// [`RawWaker`]: struct.RawWaker.html - drop: unsafe fn(*const ()), -} - -impl RawWakerVTable { - /// Creates a new `RawWakerVTable` from the provided `clone`, `wake`, - /// `wake_by_ref`, and `drop` functions. - /// - /// # `clone` - /// - /// This function will be called when the [`RawWaker`] gets cloned, e.g. when - /// the [`Waker`] in which the [`RawWaker`] is stored gets cloned. - /// - /// The implementation of this function must retain all resources that are - /// required for this additional instance of a [`RawWaker`] and associated - /// task. Calling `wake` on the resulting [`RawWaker`] should result in a wakeup - /// of the same task that would have been awoken by the original [`RawWaker`]. - /// - /// # `wake` - /// - /// This function will be called when `wake` is called on the [`Waker`]. - /// It must wake up the task associated with this [`RawWaker`]. - /// - /// The implementation of this function must make sure to release any - /// resources that are associated with this instance of a [`RawWaker`] and - /// associated task. - /// - /// # `wake_by_ref` - /// - /// This function will be called when `wake_by_ref` is called on the [`Waker`]. - /// It must wake up the task associated with this [`RawWaker`]. - /// - /// This function is similar to `wake`, but must not consume the provided data - /// pointer. - /// - /// # `drop` - /// - /// This function gets called when a [`RawWaker`] gets dropped. - /// - /// The implementation of this function must make sure to release any - /// resources that are associated with this instance of a [`RawWaker`] and - /// associated task. - /// - /// [`Waker`]: struct.Waker.html - /// [`RawWaker`]: struct.RawWaker.html - #[rustc_promotable] - #[stable(feature = "futures_api", since = "1.36.0")] - // `rustc_allow_const_fn_ptr` is a hack that should not be used anywhere else - // without first consulting with T-Lang. - // - // FIXME: remove whenever we have a stable way to accept fn pointers from const fn - // (see https://github.com/rust-rfcs/const-eval/issues/19#issuecomment-472799062) - #[rustc_allow_const_fn_ptr] - #[rustc_const_stable(feature = "futures_api", since = "1.36.0")] - pub const fn new( - clone: unsafe fn(*const ()) -> RawWaker, - wake: unsafe fn(*const ()), - wake_by_ref: unsafe fn(*const ()), - drop: unsafe fn(*const ()), - ) -> Self { - Self { clone, wake, wake_by_ref, drop } - } -} - -/// The `Context` of an asynchronous task. -/// -/// Currently, `Context` only serves to provide access to a `&Waker` -/// which can be used to wake the current task. -#[stable(feature = "futures_api", since = "1.36.0")] -pub struct Context<'a> { - waker: &'a Waker, - // Ensure we future-proof against variance changes by forcing - // the lifetime to be invariant (argument-position lifetimes - // are contravariant while return-position lifetimes are - // covariant). - _marker: PhantomData<fn(&'a ()) -> &'a ()>, -} - -impl<'a> Context<'a> { - /// Create a new `Context` from a `&Waker`. - #[stable(feature = "futures_api", since = "1.36.0")] - #[inline] - pub fn from_waker(waker: &'a Waker) -> Self { - Context { waker, _marker: PhantomData } - } - - /// Returns a reference to the `Waker` for the current task. - #[stable(feature = "futures_api", since = "1.36.0")] - #[inline] - pub fn waker(&self) -> &'a Waker { - &self.waker - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl fmt::Debug for Context<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Context").field("waker", &self.waker).finish() - } -} - -/// A `Waker` is a handle for waking up a task by notifying its executor that it -/// is ready to be run. -/// -/// This handle encapsulates a [`RawWaker`] instance, which defines the -/// executor-specific wakeup behavior. -/// -/// Implements [`Clone`], [`Send`], and [`Sync`]. -/// -/// [`RawWaker`]: struct.RawWaker.html -#[repr(transparent)] -#[stable(feature = "futures_api", since = "1.36.0")] -pub struct Waker { - waker: RawWaker, -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl Unpin for Waker {} -#[stable(feature = "futures_api", since = "1.36.0")] -unsafe impl Send for Waker {} -#[stable(feature = "futures_api", since = "1.36.0")] -unsafe impl Sync for Waker {} - -impl Waker { - /// Wake up the task associated with this `Waker`. - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn wake(self) { - // The actual wakeup call is delegated through a virtual function call - // to the implementation which is defined by the executor. - let wake = self.waker.vtable.wake; - let data = self.waker.data; - - // Don't call `drop` -- the waker will be consumed by `wake`. - crate::mem::forget(self); - - // SAFETY: This is safe because `Waker::from_raw` is the only way - // to initialize `wake` and `data` requiring the user to acknowledge - // that the contract of `RawWaker` is upheld. - unsafe { (wake)(data) }; - } - - /// Wake up the task associated with this `Waker` without consuming the `Waker`. - /// - /// This is similar to `wake`, but may be slightly less efficient in the case - /// where an owned `Waker` is available. This method should be preferred to - /// calling `waker.clone().wake()`. - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn wake_by_ref(&self) { - // The actual wakeup call is delegated through a virtual function call - // to the implementation which is defined by the executor. - - // SAFETY: see `wake` - unsafe { (self.waker.vtable.wake_by_ref)(self.waker.data) } - } - - /// Returns `true` if this `Waker` and another `Waker` have awoken the same task. - /// - /// This function works on a best-effort basis, and may return false even - /// when the `Waker`s would awaken the same task. However, if this function - /// returns `true`, it is guaranteed that the `Waker`s will awaken the same task. - /// - /// This function is primarily used for optimization purposes. - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub fn will_wake(&self, other: &Waker) -> bool { - self.waker == other.waker - } - - /// Creates a new `Waker` from [`RawWaker`]. - /// - /// The behavior of the returned `Waker` is undefined if the contract defined - /// in [`RawWaker`]'s and [`RawWakerVTable`]'s documentation is not upheld. - /// Therefore this method is unsafe. - /// - /// [`RawWaker`]: struct.RawWaker.html - /// [`RawWakerVTable`]: struct.RawWakerVTable.html - #[inline] - #[stable(feature = "futures_api", since = "1.36.0")] - pub unsafe fn from_raw(waker: RawWaker) -> Waker { - Waker { waker } - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl Clone for Waker { - #[inline] - fn clone(&self) -> Self { - Waker { - // SAFETY: This is safe because `Waker::from_raw` is the only way - // to initialize `clone` and `data` requiring the user to acknowledge - // that the contract of [`RawWaker`] is upheld. - waker: unsafe { (self.waker.vtable.clone)(self.waker.data) }, - } - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl Drop for Waker { - #[inline] - fn drop(&mut self) { - // SAFETY: This is safe because `Waker::from_raw` is the only way - // to initialize `drop` and `data` requiring the user to acknowledge - // that the contract of `RawWaker` is upheld. - unsafe { (self.waker.vtable.drop)(self.waker.data) } - } -} - -#[stable(feature = "futures_api", since = "1.36.0")] -impl fmt::Debug for Waker { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let vtable_ptr = self.waker.vtable as *const RawWakerVTable; - f.debug_struct("Waker") - .field("data", &self.waker.data) - .field("vtable", &vtable_ptr) - .finish() - } -} |
