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.
This commit is contained in:
parent
970baad714
commit
04cf534411
3 changed files with 50 additions and 1 deletions
|
|
@ -287,10 +287,24 @@ pub fn sleep(dur: Duration) {
|
|||
};
|
||||
// If we're awoken with a signal then the return value will be -1 and
|
||||
// nanosleep will fill in `ts` with the remaining time.
|
||||
while libc::nanosleep(&ts, &mut ts) == -1 {
|
||||
while dosleep(&mut ts) == -1 {
|
||||
assert_eq!(os::errno(), libc::EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
|
||||
extern {
|
||||
fn clock_nanosleep(clock_id: libc::c_int, flags: libc::c_int,
|
||||
request: *const libc::timespec,
|
||||
remain: *mut libc::timespec) -> libc::c_int;
|
||||
}
|
||||
clock_nanosleep(libc::CLOCK_MONOTONIC, 0, ts, ts)
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
unsafe fn dosleep(ts: *mut libc::timespec) -> libc::c_int {
|
||||
libc::nanosleep(ts, ts)
|
||||
}
|
||||
}
|
||||
|
||||
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ use ptr;
|
|||
use sys_common::stack::RED_ZONE;
|
||||
use sys_common::thread::*;
|
||||
use thunk::Thunk;
|
||||
use time::Duration;
|
||||
|
||||
pub type rust_thread = HANDLE;
|
||||
|
||||
|
|
@ -82,6 +83,20 @@ pub unsafe fn yield_now() {
|
|||
SwitchToThread();
|
||||
}
|
||||
|
||||
pub fn sleep(dur: Duration) {
|
||||
unsafe {
|
||||
if dur < Duration::zero() {
|
||||
return yield_now()
|
||||
}
|
||||
let ms = dur.num_milliseconds();
|
||||
// if we have a fractional number of milliseconds then add an extra
|
||||
// millisecond to sleep for
|
||||
let extra = dur - Duration::milliseconds(ms);
|
||||
let ms = ms + if extra.is_zero() {0} else {1};
|
||||
Sleep(ms as DWORD);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
extern "system" {
|
||||
fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
|
||||
|
|
@ -92,4 +107,5 @@ extern "system" {
|
|||
lpThreadId: LPDWORD) -> HANDLE;
|
||||
fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;
|
||||
fn SwitchToThread() -> BOOL;
|
||||
fn Sleep(dwMilliseconds: DWORD);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -379,6 +379,19 @@ pub fn panicking() -> bool {
|
|||
unwind::panicking()
|
||||
}
|
||||
|
||||
/// Put the current thread to sleep for the specified amount of time.
|
||||
///
|
||||
/// The thread may sleep longer than the duration specified due to scheduling
|
||||
/// specifics or platform-dependent functionality. Note that on unix platforms
|
||||
/// this function will not return early due to a signal being received or a
|
||||
/// spurious wakeup.
|
||||
#[unstable(feature = "thread_sleep",
|
||||
reason = "recently added, needs an RFC, and `Duration` itself is \
|
||||
unstable")]
|
||||
pub fn sleep(dur: Duration) {
|
||||
imp::sleep(dur)
|
||||
}
|
||||
|
||||
/// Block unless or until the current thread's token is made available (may wake spuriously).
|
||||
///
|
||||
/// See the module doc for more detail.
|
||||
|
|
@ -935,6 +948,12 @@ mod test {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sleep_smoke() {
|
||||
thread::sleep(Duration::milliseconds(2));
|
||||
thread::sleep(Duration::milliseconds(-2));
|
||||
}
|
||||
|
||||
// NOTE: the corresponding test for stderr is in run-pass/task-stderr, due
|
||||
// to the test harness apparently interfering with stderr configuration.
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue