| 1 | use pin_project_lite::pin_project; |
| 2 | use std::future::Future; |
| 3 | use std::pin::Pin; |
| 4 | use std::task::{Context, Poll}; |
| 5 | |
| 6 | pin_project! { |
| 7 | /// Future for the [`unconstrained`](unconstrained) method. |
| 8 | #[cfg_attr (docsrs, doc(cfg(feature = "rt" )))] |
| 9 | #[must_use = "Unconstrained does nothing unless polled" ] |
| 10 | pub struct Unconstrained<F> { |
| 11 | #[pin] |
| 12 | inner: F, |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | impl<F> Future for Unconstrained<F> |
| 17 | where |
| 18 | F: Future, |
| 19 | { |
| 20 | type Output = <F as Future>::Output; |
| 21 | |
| 22 | cfg_coop! { |
| 23 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 24 | let inner = self.project().inner; |
| 25 | crate::task::coop::with_unconstrained(|| inner.poll(cx)) |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | cfg_not_coop! { |
| 30 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { |
| 31 | let inner = self.project().inner; |
| 32 | inner.poll(cx) |
| 33 | } |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | /// Turn off cooperative scheduling for a future. The future will never be forced to yield by |
| 38 | /// Tokio. Using this exposes your service to starvation if the unconstrained future never yields |
| 39 | /// otherwise. |
| 40 | /// |
| 41 | /// See also the usage example in the [task module](index.html#unconstrained). |
| 42 | #[cfg_attr (docsrs, doc(cfg(feature = "rt" )))] |
| 43 | pub fn unconstrained<F>(inner: F) -> Unconstrained<F> { |
| 44 | Unconstrained { inner } |
| 45 | } |
| 46 | |