Step 2-Implementing a proper Executor 195 The next function is an important one. The spawn function allows us to register new top-level futures with our executor from anywhere in our program: ch08/b-reactor-executor/src/runtime/executor. rs pub fn spawn<F>(future: F) where F: Future<Output = String> + 'static, { CURRENT_EXEC. with(|e| { let id = e. next_id. get(); e. tasks. borrow_mut(). insert(id, Box::new(future)); e. ready_queue. lock(). map(|mut q| q. push(id)). unwrap(); e. next_id. set(id + 1); }); } The spawn function does a few things: It gets the next available ID. It assigns the ID to the future it receives and stores it in a Hash Map. It adds the ID that represents this task to ready_queue so that it's polled at least once (remember that Future traits in Rust don't do anything unless they're polled at least once). It increases the ID counter by one. The unfamiliar syntax accessing CURRENT_EXEC by calling with and passing in a closure is just a consequence of how thread local statics is implemented in Rust. Y ou'll also notice that we must use a few special methods because we use Ref Cell and Cell for internal mutability for tasks and next_id, but there is really nothing inherently complex about this except being a bit unfamiliar. A quick note about static lifetimes When a 'static lifetime is used as a trait bound as we do here, it doesn't actually mean that the lifetime of the Future trait we pass in must be static (meaning it will have to live until the end of the program). It means that it must be able to last until the end of the program, or, put another way, the lifetime can't be constrained in any way. Most often, when you encounter something that requires a 'static bound, it simply means that you'll have to give ownership over the thing you pass in. If you pass in any references, they need to have a 'static lifetime. It's less difficult to satisfy this constraint than you might expect. The final part of step 2 will be to define and implement the Executor struct itself.