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::runtime::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 | |