std::future::wait_until(time) converts time to a standard clock, and thus implicitly assumes that all clocks run at the same pace.
I was writing unit tests for various retry scenarios, such as “try again after a minute”. With naïve approach, it would lead to very long running tests, which is a no-no. To avoid the waits, I abstracted access to the clock in the code, so I could “control time”. It worked great for the most part, but
future::wait_until() refused to cooperate and gave me timeouts.
This made me wonder: how
future::wait_until() handles multiple clocks in the first place?
C++ provides two standard clock types:
system_clock, which is tied to an actual calendar time and
steady_clock, which is guaranteed to never jump back and forth, but cannot be easily converted to calendar time. In practice it is usually the time since the machine boot. In theory, it should be possible to have user-defined clock types as well.
future::wait_until() could handle a custom clock type? The answer is somewhat disappointing, but not surprising. Both GCC and MSVC implementations convert custom clock to a standard clock, and use that standard clock to wait. GCC uses vanilla
std::chrono::system_clock, MSVC uses “
xtime“, which is time in nanoseconds from some epoch. Coming to think of it, this is probably the only reasonable solution, since “clock” interface does not provide a wait facility.
This means that
wait_until assumes that all clocks move at the same pace, which may not be true in the pretend world of unit tests.
The good news is that if the future is already satisfied, i.e. the result is already available,
wait_until will ignore the time parameter, and will return immediately. So, it would work even if you pass it some weird time a few hundred years in the past.
So, the solution would be to either abstract the wait interface and avoid calling
wait_until directly, or ensure that all futures are satisfied and
wait_until is a no-op.