Extract IO polling logic to standalone abstraction