pub trait LocalWake {
    // Required method
    fn wake(self: Rc<Self>);
    // Provided method
    fn wake_by_ref(self: &Rc<Self>) { ... }
}local_waker #118959)Expand description
An analogous trait to Wake but used to construct a LocalWaker.
This API works in exactly the same way as Wake,
except that it uses an Rc instead of an Arc,
and the result is a LocalWaker instead of a Waker.
The benefits of using LocalWaker over Waker are that it allows the local waker
to hold data that does not implement Send and Sync. Additionally, it saves calls
to Arc::clone, which requires atomic synchronization.
§Examples
This is a simplified example of a spawn and a block_on function. The spawn function
is used to push new tasks onto the run queue, while the block on function will remove them
and poll them. When a task is woken, it will put itself back on the run queue to be polled
by the executor.
Note: This example trades correctness for simplicity. A real world example would interleave poll calls with calls to an io reactor to wait for events instead of spinning on a loop.
#![feature(local_waker)]
use std::task::{LocalWake, ContextBuilder, LocalWaker, Waker};
use std::future::Future;
use std::pin::Pin;
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::VecDeque;
thread_local! {
    // A queue containing all tasks ready to do progress
    static RUN_QUEUE: RefCell<VecDeque<Rc<Task>>> = RefCell::default();
}
type BoxedFuture = Pin<Box<dyn Future<Output = ()>>>;
struct Task(RefCell<BoxedFuture>);
impl LocalWake for Task {
    fn wake(self: Rc<Self>) {
        RUN_QUEUE.with_borrow_mut(|queue| {
            queue.push_back(self)
        })
    }
}
fn spawn<F>(future: F)
where
    F: Future<Output=()> + 'static + Send + Sync
{
    let task = RefCell::new(Box::pin(future));
    RUN_QUEUE.with_borrow_mut(|queue| {
        queue.push_back(Rc::new(Task(task)));
    });
}
fn block_on<F>(future: F)
where
    F: Future<Output=()> + 'static + Sync + Send
{
    spawn(future);
    loop {
        let Some(task) = RUN_QUEUE.with_borrow_mut(|queue| queue.pop_front()) else {
            // we exit, since there are no more tasks remaining on the queue
            return;
        };
        // cast the Rc<Task> into a `LocalWaker`
        let local_waker: LocalWaker = task.clone().into();
        // Build the context using `ContextBuilder`
        let mut cx = ContextBuilder::from_waker(Waker::noop())
            .local_waker(&local_waker)
            .build();
        // Poll the task
        let _ = task.0
            .borrow_mut()
            .as_mut()
            .poll(&mut cx);
    }
}
block_on(async {
    println!("hello world");
});Required Methods§
Provided Methods§
Sourcefn wake_by_ref(self: &Rc<Self>)
 🔬This is a nightly-only experimental API. (local_waker #118959)
fn wake_by_ref(self: &Rc<Self>)
local_waker #118959)Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.