Hi all,
I'm reading the async book in Applied: Build an Executor - Asynchronous Programming in Rust
In the following code of the Executor
, I assume the while let Ok(task) = self.ready_queue.recv() will take ownership of the task
from the queue. But when this loop finishes one iteration, the task
is destroyed (it is sharing owned with Arc) and the loop is blocked at self.ready_queue.recv()
to wait for a new task.
My question is then who is sharing owning the task to prevent it from destroying?
By reviewing the book, the possible place is the thread that runs the timer. But the timer thread only holds a ShareState
which has the Waker
. Then I assume the Waker is owning the Task
. But I cannot figure out the whole picture with details. Many questions remain: How the waker owns the Task
and the code is? Why the Waker will own(share) the task while the task seems to own the future in which the Waker is used?
Appreciate any help! If my question is not clear please let me know. I'll try my best to improve it.
impl Executor {
fn run(&self) {
while let Ok(task) = self.ready_queue.recv() {
// Take the future, and if it has not yet completed (is still Some),
// poll it in an attempt to complete it.
let mut future_slot = task.future.lock().unwrap();
if let Some(mut future) = future_slot.take() {
// Create a `LocalWaker` from the task itself
let waker = waker_ref(&task);
let context = &mut Context::from_waker(&*waker);
// `BoxFuture<T>` is a type alias for
// `Pin<Box<dyn Future<Output = T> + Send + 'static>>`.
// We can get a `Pin<&mut dyn Future + Send + 'static>`
// from it by calling the `Pin::as_mut` method.
if future.as_mut().poll(context).is_pending() {
// We're not done processing the future, so put it
// back in its task to be run again in the future.
*future_slot = Some(future);
}
}
}
}
}