If you implement a future, you are responsible to wake up the task when you are ready to do some more work. So normally what’s really handy, is when you are waiting on an inner future, you can just poll them and if they return Poll::Pending, they will wake up the task.
So obviously, someone needs to be at the end of the chain. So that’s why for IO there will be a “reactor” which will take care of registering tasks that need to be woken up when more IO is available (and deal with epoll and the like). So when the poll goes down the chain of futures waiting on eachother, the waker is passed down, and when it arrives at say a TcpStream, it will pass the waker to a reactor (Tokio or Romio) and when IO arrives, that reactor calls waker.wake() to wake up the task.
Now the task is polled top down again. Something polls your future, or async block, and you are await!ng the TcpStream, so your call to await! polls it, and since the task got woken by the reactor, it means there will be new data which can now bubble up all the way. Thus there are no unnecessary polls, like polling in a loop.