Skip to content

Commit 04cf534

Browse files
committed
std: Implement thread::sleep
This function is the current replacement for `std::old_io::timer` which will soon be deprecated. This function is unstable and has its own feature gate as it does not yet have an RFC nor has it existed for very long.
1 parent 970baad commit 04cf534

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/libstd/sys/unix/thread.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,24 @@ pub fn sleep(dur: Duration) {
287287
};
288288
// If we're awoken with a signal then the return value will be -1 and
289289
// nanosleep will fill in `ts` with the remaining time.
290-
while libc::nanosleep(&ts, &mut ts) == -1 {
290+
while dosleep(&mut ts) == -1 {
291291
assert_eq!(os::errno(), libc::EINTR);
292292
}
293293
}
294+
295+
#[cfg(target_os = "linux")]
296+
unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
297+
extern {
298+
fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
299+
request: *const libc::timespec,
300+
remain: *mut libc::timespec) -> libc::c_int;
301+
}
302+
clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
303+
}
304+
#[cfg(not(target_os = "linux"))]
305+
unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
306+
libc::nanosleep(ts, ts)
307+
}
294308
}
295309

296310
// glibc >= 2.15 has a __pthread_get_minstack() function that returns

src/libstd/sys/windows/thread.rs

+16
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use ptr;
2020
use sys_common::stack::RED_ZONE;
2121
use sys_common::thread::*;
2222
use thunk::Thunk;
23+
use time::Duration;
2324

2425
pub type rust_thread = HANDLE;
2526

@@ -82,6 +83,20 @@ pub unsafe fn yield_now() {
8283
SwitchToThread();
8384
}
8485

86+
pub fn sleep(dur: Duration) {
87+
unsafe {
88+
if dur < Duration::zero() {
89+
return yield_now()
90+
}
91+
let ms = dur.num_milliseconds();
92+
// if we have a fractional number of milliseconds then add an extra
93+
// millisecond to sleep for
94+
let extra = dur - Duration::milliseconds(ms);
95+
let ms = ms + if extra.is_zero() {0} else {1};
96+
Sleep(ms as DWORD);
97+
}
98+
}
99+
85100
#[allow(non_snake_case)]
86101
extern "system" {
87102
fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
@@ -92,4 +107,5 @@ extern "system" {
92107
lpThreadId: LPDWORD) -> HANDLE;
93108
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
94109
fn SwitchToThread() -> BOOL;
110+
fn Sleep(dwMilliseconds: DWORD);
95111
}

src/libstd/thread.rs

+19
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,19 @@ pub fn panicking() -> bool {
379379
unwind::panicking()
380380
}
381381

382+
/// Put the current thread to sleep for the specified amount of time.
383+
///
384+
/// The thread may sleep longer than the duration specified due to scheduling
385+
/// specifics or platform-dependent functionality. Note that on unix platforms
386+
/// this function will not return early due to a signal being received or a
387+
/// spurious wakeup.
388+
#[unstable(feature = "thread_sleep",
389+
reason = "recently added, needs an RFC, and `Duration` itself is \
390+
unstable")]
391+
pub fn sleep(dur: Duration) {
392+
imp::sleep(dur)
393+
}
394+
382395
/// Block unless or until the current thread's token is made available (may wake spuriously).
383396
///
384397
/// See the module doc for more detail.
@@ -935,6 +948,12 @@ mod test {
935948
}
936949
}
937950

951+
#[test]
952+
fn sleep_smoke() {
953+
thread::sleep(Duration::milliseconds(2));
954+
thread::sleep(Duration::milliseconds(-2));
955+
}
956+
938957
// NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
939958
// to the test harness apparently interfering with stderr configuration.
940959
}

0 commit comments

Comments
 (0)