[][src]Module async_io::parking

Thread parking and unparking.

This module exposes the exact same API as the parking crate. The only difference is that Parker in this module will wait on epoll/kqueue/wepoll and wake futures blocked on I/O or timers instead of just sleeping.

Executors may use this mechanism to go to sleep when idle and wake up when more work is scheduled. The benefit is in that when going to sleep using Parker, futures blocked on I/O or timers will often be woken and polled by the same executor thread. This is sometimes a significant optimization because no context switch is needed between waiting on I/O and polling futures.

Examples

A simple block_on() that runs a single future and waits on I/O when the future is idle:

use std::future::Future;
use std::task::{Context, Poll};

use async_io::parking;
use futures_lite::{future, pin};
use waker_fn::waker_fn;

// Blocks on a future to complete, processing I/O events when idle.
fn block_on<T>(future: impl Future<Output = T>) -> T {
    let (p, u) = parking::pair();
    let waker = waker_fn(move || u.unpark());
    let cx = &mut Context::from_waker(&waker);

    pin!(future);
    loop {
        match future.as_mut().poll(cx) {
            Poll::Ready(t) => return t,
            Poll::Pending => {
                // Wait until unparked, processing I/O events in the meantime.
                p.park();
            }
        }
    }
}

block_on(async {
    println!("Hello world!");
    future::yield_now().await;
    println!("Hello again!");
});

Structs

Parker

Waits for a notification.

Unparker

Notifies a parker.

Functions

pair

Creates a parker and an associated unparker.