pub fn poll_proceed(cx: &mut Context<'_>) -> Poll<RestoreOnPending>Expand description
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 wraps the futures::channel::mpsc::UnboundedReceiver to
cooperate with the Tokio scheduler. Each time a value is received, task budget
is consumed. If no budget is available, the task yields to the scheduler.
use std::pin::Pin;
use std::task::{ready, Context, Poll};
use tokio::task::coop;
use futures::stream::{Stream, StreamExt};
use futures::channel::mpsc::UnboundedReceiver;
struct CoopUnboundedReceiver<T> {
receiver: UnboundedReceiver<T>,
}
impl<T> Stream for CoopUnboundedReceiver<T> {
type Item = T;
fn poll_next(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>
) -> Poll<Option<T>> {
let coop = ready!(coop::poll_proceed(cx));
match self.receiver.poll_next_unpin(cx) {
Poll::Ready(v) => {
// We received a value, so consume budget.
coop.made_progress();
Poll::Ready(v)
}
Poll::Pending => Poll::Pending,
}
}
}