Repository: tokio-rs/tokio
File: tokio/src/task/coop/mod.rs (Rust)

Code before:
        }
    }

    /// Decrements the task budget and returns `Poll::Pending` if the budget is depleted.
    /// This indicates that the task should yield to the scheduler. Otherwise, returns
    /// `RestoreOnPending` which can be used to commit the budget consumption.
    ///
    /// The returned [`RestoreOnPending`](RestoreOnPending) will revert the budget to its former
    /// value when dropped unless [`RestoreOnPending::made_progress`](RestoreOnPending::made_progress)
    /// is called. It is the caller's responsibility to do so when it _was_ able to
    /// make progress after the call to `poll_pending`.
    /// Restoring the budget automatically ensures the task can try to make progress in some other
    /// way.
    ///
    /// Note that `RestoreOnPending` restores the budget **as it was before `poll_proceed`**.
    /// Therefore, if the budget is _further_ adjusted between when `poll_proceed` returns and
    /// `RestoreOnPending` is dropped, those adjustments are erased unless the caller indicates
    /// that progress was made.
    ///
    /// # Examples
    ///
    /// This example shows a `Future` implementation that uses `poll_proceed` to participate in
    /// cooperative scheduling. If the work to be done consists of polling another future, consider
    /// using the higher-level [`cooperative`](cooperative) function instead.
    ///
    /// ```ignore
    /// use std::future::Future;
    /// use std::pin::Pin;
    /// use std::task::{ready, Context, Poll};
    ///
    /// impl<T> Future for CooperativeFuture<T> {
    ///    type Output = T;
    ///
    ///    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
    ///        // `poll_proceed` checks with the runtime if this task is still allowed to proceed
    ///        // with performing work.
    ///        // If not, `Pending` is returned and `ready!` ensure this
    ///        // function returns.
    ///        // If we are allowed to proceed, coop now represents the budget consumption
    ///        let coop = ready!(tokio::task::coop::poll_proceed(cx));
    ///
    ///        // Here we try to do some work
    ///        // If for some reason that's not possible and we exit the function with `Pending`
    ///        // the drop of `coop` will ensure the consumed budget is restored freeing it up
    ///        // for use elsewhere.
    ///        let ret : Poll<T> = ...;
    ///
    ///        // If the value we will return is `Ready(_)` the task did perform some actual work
    ///        // and the task budget consumption needs to be committed. We do that by calling
    ///        // `made_progress`. It is essential that this call is made because otherwise the
    ///        // the budget will be restored and the task may keep running indefinitely.

Review comment (suggestion):
We generally try pretty hard to avoid `ignore` on doctests. Please try to make the doc-test compile.

Code after:
            // Don't reset if budget was unconstrained or if we made progress.
            // They are both represented as the remembered budget being unconstrained.
            let budget = self.0.get();
            if !budget.is_unconstrained() {
                let _ = context::budget(|cell| {
                    cell.set(budget);
                });
            }
        }
    }

    /// Decrements the task budget and returns [`Poll::Pending`] if the budget is depleted.
    /// This indicates that the task should yield to the scheduler. Otherwise, returns
    /// [`RestoreOnPending`] which can be used to commit the budget consumption.
    ///
    /// The returned [`RestoreOnPending`] will revert the budget to its former
    /// value when dropped unless [`RestoreOnPending::made_progress`]
    /// is called. It is the caller's responsibility to do so when it _was_ able to
    /// make progress after the call to [`poll_proceed`].
    /// Restoring the budget automatically ensures the task can try to make progress in some other
    /// way.
    ///
    /// Note that [`RestoreOnPending`] restores the budget **as it was before [`poll_proceed`]**.
    /// Therefore, if the budget is _further_ adjusted between when [`poll_proceed`] returns and
    /// [`RestoreOnPending`] is dropped, those adjustments are erased unless the caller indicates
    /// that progress was made.
    ///
    /// # Examples
    ///
    /// This example shows a simple countdown latch that uses [`poll_proceed`] to participate in
    /// cooperative scheduling.
    ///
    /// ```
    /// use std::future::{Future};
    /// use std::pin::Pin;
    /// use std::task::{ready, Context, Poll, Waker};
    /// use tokio::task::coop;
    ///
    /// struct CountdownLatch<T> {
    ///     counter: usize,
    ///     value: Option<T>,
    ///     waker: Option<Waker>
    /// }
    ///
    /// impl<T> CountdownLatch<T> {
    ///     fn new(value: T, count: usize) -> Self {
    ///         CountdownLatch {
    ///             counter: count,
    ///             value: Some(value),
    ///             waker: None
    ///         }