native: Move from usleep() to nanosleep()
Using nanosleep() allows us to gracefully recover from EINTR because on error it fills in the second parameter with the remaining time to sleep. Closes #12689
This commit is contained in:
parent
8334dd445f
commit
d8bd8de82e
3 changed files with 22 additions and 6 deletions
|
|
@ -218,8 +218,15 @@ impl Timer {
|
|||
}
|
||||
|
||||
pub fn sleep(ms: u64) {
|
||||
// FIXME: this can fail because of EINTR, what do do?
|
||||
let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
|
||||
let mut to_sleep = libc::timespec {
|
||||
tv_sec: (ms / 1000) as libc::time_t,
|
||||
tv_nsec: ((ms % 1000) * 1000000) as libc::c_long,
|
||||
};
|
||||
while unsafe { libc::nanosleep(&to_sleep, &mut to_sleep) } != 0 {
|
||||
if os::errno() as int != libc::EINTR as int {
|
||||
fail!("failed to sleep, but not because of EINTR?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inner(&mut self) -> ~Inner {
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@
|
|||
//! why).
|
||||
//!
|
||||
//! As with timer_other, timers just using sleep() do not use the timerfd at
|
||||
//! all. They remove the timerfd from the worker thread and then invoke usleep()
|
||||
//! to block the calling thread.
|
||||
//! all. They remove the timerfd from the worker thread and then invoke
|
||||
//! nanosleep() to block the calling thread.
|
||||
//!
|
||||
//! As with timer_other, all units in this file are in units of millseconds.
|
||||
|
||||
|
|
@ -183,8 +183,15 @@ impl Timer {
|
|||
}
|
||||
|
||||
pub fn sleep(ms: u64) {
|
||||
// FIXME: this can fail because of EINTR, what do do?
|
||||
let _ = unsafe { libc::usleep((ms * 1000) as libc::c_uint) };
|
||||
let mut to_sleep = libc::timespec {
|
||||
tv_sec: (ms / 1000) as libc::time_t,
|
||||
tv_nsec: ((ms % 1000) * 1000000) as libc::c_long,
|
||||
};
|
||||
while unsafe { libc::nanosleep(&to_sleep, &mut to_sleep) } != 0 {
|
||||
if os::errno() as int != libc::EINTR as int {
|
||||
fail!("failed to sleep, but not because of EINTR?");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn remove(&mut self) {
|
||||
|
|
|
|||
|
|
@ -3682,6 +3682,7 @@ pub mod funcs {
|
|||
use libc::types::common::c95::c_void;
|
||||
use libc::types::os::arch::c95::{c_char, c_int, c_long, c_uint};
|
||||
use libc::types::os::arch::c95::{size_t};
|
||||
use libc::types::os::common::posix01::timespec;
|
||||
use libc::types::os::arch::posix01::utimbuf;
|
||||
use libc::types::os::arch::posix88::{gid_t, off_t, pid_t};
|
||||
use libc::types::os::arch::posix88::{ssize_t, uid_t};
|
||||
|
|
@ -3731,6 +3732,7 @@ pub mod funcs {
|
|||
pub fn setuid(uid: uid_t) -> c_int;
|
||||
pub fn sleep(secs: c_uint) -> c_uint;
|
||||
pub fn usleep(secs: c_uint) -> c_int;
|
||||
pub fn nanosleep(rqtp: *timespec, rmtp: *mut timespec) -> c_int;
|
||||
pub fn sysconf(name: c_int) -> c_long;
|
||||
pub fn tcgetpgrp(fd: c_int) -> pid_t;
|
||||
pub fn ttyname(fd: c_int) -> *c_char;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue