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,
}
}
}