tokio/task/consume_budget.rs
1use std::task::{ready, Poll};
2
3/// Consumes a unit of budget and returns the execution back to the Tokio
4/// runtime *if* the task's coop budget was exhausted.
5///
6/// The task will only yield if its entire coop budget has been exhausted.
7/// This function can be used in order to insert optional yield points into long
8/// computations that do not use Tokio resources like sockets or semaphores,
9/// without redundantly yielding to the runtime each time.
10///
11/// # Examples
12///
13/// Make sure that a function which returns a sum of (potentially lots of)
14/// iterated values is cooperative.
15///
16/// ```
17/// async fn sum_iterator(input: &mut impl std::iter::Iterator<Item=i64>) -> i64 {
18/// let mut sum: i64 = 0;
19/// while let Some(i) = input.next() {
20/// sum += i;
21/// tokio::task::consume_budget().await
22/// }
23/// sum
24/// }
25/// ```
26#[cfg_attr(docsrs, doc(cfg(feature = "rt")))]
27pub async fn consume_budget() {
28 let mut status = Poll::Pending;
29
30 std::future::poll_fn(move |cx| {
31 ready!(crate::trace::trace_leaf(cx));
32 if status.is_ready() {
33 return status;
34 }
35 status = crate::runtime::coop::poll_proceed(cx).map(|restore| {
36 restore.made_progress();
37 });
38 status
39 })
40 .await
41}