@@ -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