Function sleep_until

fn sleep_until(deadline: Instant)

Puts the current thread to sleep until the specified deadline has passed.

The thread may still be asleep after the deadline specified due to scheduling specifics or platform-dependent functionality. It will never wake before.

This function is blocking, and should not be used in async functions.

Platform-specific behavior

In most cases this function will call an OS specific function. Where that is not supported sleep is used. Those platforms are referred to as other in the table below.

Underlying System calls

The following system calls are currently being used:

Platform System call
Linux clock_nanosleep (Monotonic clock)
BSD except OpenBSD clock_nanosleep (Monotonic Clock)]
Android clock_nanosleep (Monotonic Clock)]
Solaris clock_nanosleep (Monotonic Clock)]
Illumos clock_nanosleep (Monotonic Clock)]
Dragonfly clock_nanosleep (Monotonic Clock)]
Hurd clock_nanosleep (Monotonic Clock)]
Vxworks clock_nanosleep (Monotonic Clock)]
Apple mach_wait_until
Other sleep_until uses sleep and does not issue a syscall itself

Disclaimer: These system calls might change over time.

Examples

A simple game loop that limits the game to 60 frames per second.

#![feature(thread_sleep_until)]
# use std::time::{Duration, Instant};
# use std::thread;
#
# fn update() {}
# fn render() {}
#
let max_fps = 60.0;
let frame_time = Duration::from_secs_f32(1.0/max_fps);
let mut next_frame = Instant::now();
loop {
    thread::sleep_until(next_frame);
    next_frame += frame_time;
    update();
    render();
}

A slow API we must not call too fast and which takes a few tries before succeeding. By using sleep_until the time the API call takes does not influence when we retry or when we give up

#![feature(thread_sleep_until)]
# use std::time::{Duration, Instant};
# use std::thread;
#
# enum Status {
#     Ready(usize),
#     Waiting,
# }
# fn slow_web_api_call() -> Status { Status::Ready(42) }
#
# const MAX_DURATION: Duration = Duration::from_secs(10);
#
# fn try_api_call() -> Result<usize, ()> {
let deadline = Instant::now() + MAX_DURATION;
let delay = Duration::from_millis(250);
let mut next_attempt = Instant::now();
loop {
    if Instant::now() > deadline {
        break Err(());
    }
    if let Status::Ready(data) = slow_web_api_call() {
        break Ok(data);
    }

    next_attempt = deadline.min(next_attempt + delay);
    thread::sleep_until(next_attempt);
}
# }
# let _data = try_api_call();