mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-08-04 23:17:46 +00:00
Prefer handling Duration
over f32
when dealing with times.
Also refactored out usage of the `time` crate in `uucore`.
This commit is contained in:
parent
463c6af4e3
commit
72d2ab208c
4 changed files with 20 additions and 18 deletions
|
@ -5,7 +5,6 @@ authors = []
|
|||
|
||||
[dependencies]
|
||||
libc = "*"
|
||||
time = "*"
|
||||
winapi = "*"
|
||||
|
||||
[lib]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
extern crate libc;
|
||||
extern crate time;
|
||||
#[cfg(windows)] extern crate winapi;
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
pub fn from_str(string: &str) -> Result<f64, String> {
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn from_str(string: &str) -> Result<Duration, String> {
|
||||
let len = string.len();
|
||||
if len == 0 {
|
||||
return Err("empty string".to_owned())
|
||||
|
@ -28,8 +30,14 @@ pub fn from_str(string: &str) -> Result<f64, String> {
|
|||
}
|
||||
}
|
||||
};
|
||||
match numstr.parse::<f64>() {
|
||||
Ok(m) => Ok(m * times as f64),
|
||||
Err(e) => Err(format!("invalid time interval '{}': {}", string, e))
|
||||
}
|
||||
let num = match numstr.parse::<f64>() {
|
||||
Ok(m) => m,
|
||||
Err(e) => return Err(format!("invalid time interval '{}': {}", string, e))
|
||||
};
|
||||
|
||||
const NANOS_PER_SEC: u32 = 1_000_000_000;
|
||||
let whole_secs = num.trunc();
|
||||
let nanos = (num.fract() * (NANOS_PER_SEC as f64)).trunc();
|
||||
let duration = Duration::new(whole_secs as u64, nanos as u32);
|
||||
Ok(duration * times)
|
||||
}
|
||||
|
|
|
@ -15,8 +15,7 @@ use std::io;
|
|||
use std::process::Child;
|
||||
use std::sync::{Arc, Condvar, Mutex};
|
||||
use std::thread;
|
||||
use time::{Duration, get_time};
|
||||
use std::time::Duration as StdDuration;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
// This is basically sys::unix::process::ExitStatus
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
|
@ -71,7 +70,7 @@ pub trait ChildExt {
|
|||
fn send_signal(&mut self, signal: usize) -> io::Result<()>;
|
||||
|
||||
/// Wait for a process to finish or return after the specified duration.
|
||||
fn wait_or_timeout(&mut self, timeout: f64) -> io::Result<Option<ExitStatus>>;
|
||||
fn wait_or_timeout(&mut self, timeout: Duration) -> io::Result<Option<ExitStatus>>;
|
||||
}
|
||||
|
||||
impl ChildExt for Child {
|
||||
|
@ -84,7 +83,7 @@ impl ChildExt for Child {
|
|||
}
|
||||
}
|
||||
|
||||
fn wait_or_timeout(&mut self, timeout: f64) -> io::Result<Option<ExitStatus>> {
|
||||
fn wait_or_timeout(&mut self, timeout: Duration) -> io::Result<Option<ExitStatus>> {
|
||||
// The result will be written to that Option, protected by a Mutex
|
||||
// Then the Condvar will be signaled
|
||||
let state = Arc::new((
|
||||
|
@ -116,16 +115,13 @@ impl ChildExt for Child {
|
|||
let &(ref lock, ref cvar) = &*state;
|
||||
let mut exitstatus = lock.lock().unwrap();
|
||||
// Condvar::wait_timeout_ms() can wake too soon, in this case wait again
|
||||
let target = get_time() +
|
||||
Duration::seconds(timeout as i64) +
|
||||
Duration::nanoseconds((timeout * 1.0e-6) as i64);
|
||||
let start = Instant::now();
|
||||
while exitstatus.is_none() {
|
||||
let now = get_time();
|
||||
if now >= target {
|
||||
if start.elapsed() >= timeout {
|
||||
return Ok(None)
|
||||
}
|
||||
let ms = (target - get_time()).num_milliseconds() as u32;
|
||||
exitstatus = cvar.wait_timeout(exitstatus, StdDuration::new(0, ms*1000)).unwrap().0;
|
||||
let cvar_timeout = timeout - start.elapsed();
|
||||
exitstatus = cvar.wait_timeout(exitstatus, cvar_timeout).unwrap().0;
|
||||
}
|
||||
|
||||
// Turn Option<Result<ExitStatus>> into Result<Option<ExitStatus>>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue