Skip to content

Commit 016a574

Browse files
committed
task: improve the example of poll_proceed
Signed-off-by: ADD-SP <[email protected]>
1 parent 86400a1 commit 016a574

File tree

1 file changed

+28
-59
lines changed

1 file changed

+28
-59
lines changed

tokio/src/task/coop/mod.rs

Lines changed: 28 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -306,75 +306,44 @@ cfg_coop! {
306306
///
307307
/// # Examples
308308
///
309-
/// This example shows a simple countdown latch that uses [`poll_proceed`] to participate in
310-
/// cooperative scheduling.
309+
/// This example shows a simple async `Zero` reader that acts like [`/dev/zero`], and uses
310+
/// `poll_proceed` to cooperate with the Tokio scheduler.
311311
///
312312
/// ```
313-
/// use std::future::{Future};
314313
/// use std::pin::Pin;
315-
/// use std::task::{ready, Context, Poll, Waker};
314+
/// use std::io::Result as IoResult;
315+
/// use std::task::{ready, Context, Poll};
316316
/// use tokio::task::coop;
317+
/// use tokio::io::{AsyncRead, ReadBuf};
317318
///
318-
/// struct CountdownLatch<T> {
319-
/// counter: usize,
320-
/// value: Option<T>,
321-
/// waker: Option<Waker>
322-
/// }
323-
///
324-
/// impl<T> CountdownLatch<T> {
325-
/// fn new(value: T, count: usize) -> Self {
326-
/// CountdownLatch {
327-
/// counter: count,
328-
/// value: Some(value),
329-
/// waker: None
330-
/// }
331-
/// }
332-
/// fn count_down(&mut self) {
333-
/// if self.counter <= 0 {
334-
/// return;
335-
/// }
336-
///
337-
/// self.counter -= 1;
338-
/// if self.counter == 0 {
339-
/// if let Some(w) = self.waker.take() {
340-
/// w.wake();
341-
/// }
342-
/// }
343-
/// }
344-
/// }
345-
///
346-
/// impl<T> Future for CountdownLatch<T> {
347-
/// type Output = T;
348-
///
349-
/// fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
350-
/// // `poll_proceed` checks with the runtime if this task is still allowed to proceed
351-
/// // with performing work.
352-
/// // If not, `Pending` is returned and `ready!` ensures this function returns.
353-
/// // If we are allowed to proceed, coop now represents the budget consumption
354-
/// let coop = ready!(coop::poll_proceed(cx));
319+
/// struct Zero;
355320
///
356-
/// // Get a mutable reference to the CountdownLatch
357-
/// let this = Pin::get_mut(self);
321+
/// impl AsyncRead for Zero {
322+
/// fn poll_read(
323+
/// self: Pin<&mut Self>,
324+
/// cx: &mut Context<'_>,
325+
/// buf: &mut ReadBuf<'_>
326+
/// ) -> Poll<IoResult<()>> {
327+
/// const ZEROES: [u8; 64] = [0; 64];
358328
///
359-
/// // Next we check if the latch is ready to release its value
360-
/// if this.counter == 0 {
361-
/// let t = this.value.take();
362-
/// // The latch made progress so call `made_progress` to ensure the budget
363-
/// // is not reverted.
364-
/// coop.made_progress();
365-
/// Poll::Ready(t.unwrap())
366-
/// } else {
367-
/// // If the latch is not ready so return pending and simply drop `coop`.
368-
/// // This will restore the budget making it available again to perform any
369-
/// // other work.
370-
/// this.waker = Some(cx.waker().clone());
371-
/// Poll::Pending
372-
/// }
329+
/// let coop = ready!(coop::poll_proceed(cx));
330+
/// if buf.remaining() == 0 {
331+
/// Poll::Ready(Ok(()))
332+
/// } else {
333+
/// while buf.remaining() > 0 {
334+
/// let len = ZEROES.len().min(buf.remaining());
335+
/// buf.put_slice(&ZEROES[..len]);
336+
/// }
337+
/// // we have made progress, so don't restore the budget
338+
/// // when `coop` is dropped.
339+
/// coop.made_progress();
340+
/// Poll::Pending
341+
/// }
373342
/// }
374343
/// }
375-
///
376-
/// impl<T> Unpin for CountdownLatch<T> {}
377344
/// ```
345+
///
346+
/// [`/dev/zero`]: https://man7.org/linux/man-pages/man4/zero.4.html
378347
#[inline]
379348
pub fn poll_proceed(cx: &mut Context<'_>) -> Poll<RestoreOnPending> {
380349
context::budget(|cell| {

0 commit comments

Comments
 (0)