#2006·mio

Windows: `Poll::poll` timeout is extended by system suspend

Author: GlenDCCreated Aug 25, 2026Updated Aug 25, 2026

Summary

On Windows, time spent suspended is not counted towards the relative timeout passed to GetQueuedCompletionStatusEx (https://learn.microsoft.com/en-us/windows/win32/fileio/getqueuedcompletionstatusex-func). As a result, Poll::poll can remain blocked after resume even when the caller's Instant-based deadline has already passed.

We encountered this through Tokio and have a deterministic reproduction in tokio-rs/tokio#8344. Microsoft documents that, since Windows 8, the timeout does not include time spent in low-power states.

We are not Windows power-management experts, and it is not entirely clear to us whether Mio intends the timeout to represent active time or elapsed monotonic time. In practice, Tokio derives it from an Instant deadline, and in our reproduction Instant advances while the machine is suspended.

Considered approaches

Tokio could cap every poll timeout and wake periodically, but that adds otherwise unnecessary wake-ups.

Using a Windows waitable timer also seems possible, though integrating and cancelling it through IOCP appears considerably more involved.

Possible direction

One potentially smaller approach is registering for suspend/resume notifications with PowerRegisterSuspendResumeNotification (https://learn.microsoft.com/en-us/windows/win32/api/powerbase/nf-powerbase-powerregistersuspendresumenotification). On resume, the callback could post a private completion to Mio's existing IOCP. Mio would filter that event and recalculate the remaining timeout from its original Instant deadline.

This would require no periodic wake-up, helper thread, or public API change.

Would this be an appropriate direction for Mio, or should the timeout continue to follow the underlying Windows active-time semantics?

Environment

Environment that we experimented on:

  • Windows 11
  • mio 1.2.2
  • tokio 1.53.1

Prior Art