diff --git a/src/4_generators_async_await.md b/src/4_generators_async_await.md index 154c964..56efc7c 100644 --- a/src/4_generators_async_await.md +++ b/src/4_generators_async_await.md @@ -73,7 +73,7 @@ the needed state increases with each added step. This is the model used in Rust today. It has a few notable advantages: -1. It's easy to convert normal Rust code to a stackless coroutine using using +1. It's easy to convert normal Rust code to a stackless coroutine using async/await as keywords (it can even be done using a macro). 2. No need for context switching and saving/restoring CPU state 3. No need to handle dynamic stack allocation diff --git a/src/5_pin.md b/src/5_pin.md index 7b5741b..86e7545 100644 --- a/src/5_pin.md +++ b/src/5_pin.md @@ -34,7 +34,7 @@ On a more serious note, I feel obliged to mention that there are valid reasons for the names that were chosen. Naming is not easy, and I considered renaming `Unpin` and `!Unpin` in this book to make them easier to reason about. -However, an experienced member of the Rust community convinced me that that there +However, an experienced member of the Rust community convinced me that there are just too many nuances and edge-cases to consider which are easily overlooked when naively giving these markers different names, and I'm convinced that we'll just have to get used to them and use them as is. diff --git a/src/7_finished_example.md b/src/7_finished_example.md index f42dd97..ea05a39 100644 --- a/src/7_finished_example.md +++ b/src/7_finished_example.md @@ -28,9 +28,17 @@ fn main() { } use std::{ - future::Future, sync::{ mpsc::{channel, Sender}, Arc, Mutex, Condvar}, - task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, mem, pin::Pin, - thread::{self, JoinHandle}, time::{Duration, Instant}, collections::HashMap + collections::HashMap, + future::Future, + mem, + pin::Pin, + sync::{ + mpsc::{channel, Sender}, + Arc, Condvar, Mutex, + }, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, + thread::{self, JoinHandle}, + time::{Duration, Instant}, }; // ============================= EXECUTOR ==================================== #[derive(Default)] @@ -39,9 +47,9 @@ struct Parker(Mutex, Condvar); impl Parker { fn park(&self) { let mut resumable = self.0.lock().unwrap(); - while !*resumable { - resumable = self.1.wait(resumable).unwrap(); - } + while !*resumable { + resumable = self.1.wait(resumable).unwrap(); + } *resumable = false; } @@ -53,7 +61,9 @@ impl Parker { fn block_on(mut future: F) -> F::Output { let parker = Arc::new(Parker::default()); - let mywaker = Arc::new(MyWaker { parker: parker.clone() }); + let mywaker = Arc::new(MyWaker { + parker: parker.clone(), + }); let waker = mywaker_into_waker(Arc::into_raw(mywaker)); let mut cx = Context::from_waker(&waker); @@ -116,8 +126,8 @@ impl Future for Task { if r.is_ready(self.id) { *r.tasks.get_mut(&self.id).unwrap() = TaskState::Finished; Poll::Ready(self.id) - } else if r.tasks.contains_key(&self.id) { - r.tasks.insert(self.id, TaskState::NotReady(cx.waker().clone())); + } else if let std::collections::hash_map::Entry::Occupied(mut e) = r.tasks.entry(self.id) { + e.insert(TaskState::NotReady(cx.waker().clone())); Poll::Pending } else { r.register(self.data, cx.waker().clone(), self.id); @@ -169,7 +179,9 @@ impl Reactor { } } } - handles.into_iter().for_each(|handle| handle.join().unwrap()); + handles + .into_iter() + .for_each(|handle| handle.join().unwrap()); }); reactor.lock().map(|mut r| r.handle = Some(handle)).unwrap(); reactor @@ -180,7 +192,7 @@ impl Reactor { match mem::replace(state, TaskState::Ready) { TaskState::NotReady(waker) => waker.wake(), TaskState::Finished => panic!("Called 'wake' twice on task: {}", id), - _ => unreachable!() + _ => unreachable!(), } } @@ -192,10 +204,10 @@ impl Reactor { } fn is_ready(&self, id: usize) -> bool { - self.tasks.get(&id).map(|state| match state { - TaskState::Ready => true, - _ => false, - }).unwrap_or(false) + self.tasks + .get(&id) + .map(|state| matches!(state, TaskState::Ready)) + .unwrap_or(false) } }