Runtimes, Wakers, and the Reactor-Executor Pattern 194 The thread_local! macro lets us define a static variable that's unique to the thread it's first called from. This means that all threads we create will have their own instance, and it's impossible for one thread to access another thread's CURRENT_EXEC variable. We call the variable CURRENT_EXEC since it holds the Executor that's currently running on this thread. The next lines we add to this file is the definition of Executor Core : ch08/b-reactor-executor/src/runtime/executor. rs #[derive(Default)] struct Executor Core { tasks: Ref Cell<Hash Map<usize, Task>>, ready_queue: Arc<Mutex<Vec<usize>>>, next_id: Cell<usize>, } Executor Core holds all the state for our Executor : tasks -This is a Hash Map with a usize as the key and a Task (remember the alias we created previously) as data. This will hold all the top-level futures associated with the executor on this thread and allow us to give each an id property to identify them. We can't simply mutate a static variable, so we need internal mutability here. Since this will only be callable from one thread, a Ref Cell will do so since there is no need for synchronization. ready_queue -This is a simple Vec<usize> that stores the IDs of tasks that should be polled by the executor. If we refer back to Figure 8. 7, you'll see how this fits into the design we outlined there. As mentioned earlier, we could store something such as an Arc<dyn Future<... >> here instead, but that adds quite a bit of complexity to our example. The only downside with the current design is that instead of getting a reference to the task directly, we have to look it up in our tasks collection, which takes time. An Arc<... > (shared reference) to this collection will be given to each Waker that this executor creates. Since the Waker can (and will) be sent to a different thread and signal that a specific task is ready by adding the task's ID to ready_queue, we need to wrap it in an Arc<Mutex<... >>. next_id -This is a counter that gives out the next available I, which means that it should never hand out the same ID twice for this executor instance. We'll use this to give each top-level future a unique ID. Since the executor instance will only be accessible on the same thread it was created, a simple Cell will suffice in giving us the internal mutability we need. Executor Core derives the Default trait since there is no special initial state we need here, and it keeps the code short and concise.