Runtimes, Wakers, and the Reactor-Executor Pattern 188 |--http. rs |--main. rs |--runtime. rs To set everything up, we start by deleting everything in runtime. rs and replacing it with the following lines of code: ch08/b-reactor-executor/src/runtime. rs pub use executor::{spawn, Executor, Waker}; pub use reactor::reactor; mod executor; mod reactor; pub fn init()-> Executor { reactor::start(); Executor::new() } The new content of runtime. rs first declares two submodules called executor and reactor. We then declare one function called init that starts our Reactor and creates a new Executor that it returns to the caller. The next point on our list is to find a way for our Executor to sleep and wake up when needed without relying on Poll. Creating a Waker So, we need to find a different way for our executor to sleep and get woken up that doesn't rely directly on Poll. It turns out that this is quite easy. The standard library gives us what we need to get something working. By calling std::thread::current(), we can get a Thread object. This object is a handle to the current thread, and it gives us access to a few methods, one of which is unpark. The standard library also gives us a method called std::thread::park(), which simply asks the OS scheduler to park our thread until we ask for it to get unparked later on. It turns out that if we combine these, we have a way to both park and unpark the executor, which is exactly what we need. Let's create a Waker type based on this. In our example, we'll define the Waker inside the executor module since that's where we create this exact type of Waker, but you could argue that it belongs to the future module since it's a part of the Future trait.