diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sys/select.rs | 10 | ||||
-rw-r--r-- | src/sys/time.rs | 91 |
2 files changed, 74 insertions, 27 deletions
diff --git a/src/sys/select.rs b/src/sys/select.rs index 28b664aa..c9e925dd 100644 --- a/src/sys/select.rs +++ b/src/sys/select.rs @@ -1,6 +1,6 @@ use std::ptr::null_mut; use std::os::unix::io::RawFd; -use libc::c_int; +use libc::{c_int, timeval}; use {Errno, Result}; use sys::time::TimeVal; @@ -56,8 +56,7 @@ impl FdSet { } mod ffi { - use libc::c_int; - use sys::time::TimeVal; + use libc::{c_int, timeval}; use super::FdSet; extern { @@ -65,7 +64,7 @@ mod ffi { readfds: *mut FdSet, writefds: *mut FdSet, errorfds: *mut FdSet, - timeout: *mut TimeVal) -> c_int; + timeout: *mut timeval) -> c_int; } } @@ -77,7 +76,8 @@ pub fn select(nfds: c_int, let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut()); let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut()); let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut()); - let timeout = timeout.map(|tv| tv as *mut TimeVal).unwrap_or(null_mut()); + let timeout = timeout.map(|tv| &mut tv.timeval() as *mut timeval) + .unwrap_or(null_mut()); let res = unsafe { ffi::select(nfds, readfds, writefds, errorfds, timeout) diff --git a/src/sys/time.rs b/src/sys/time.rs index 31c194fb..8340c9d0 100644 --- a/src/sys/time.rs +++ b/src/sys/time.rs @@ -1,12 +1,9 @@ -use std::{fmt, ops}; -use libc::{time_t, suseconds_t}; +use std::{cmp, fmt, ops}; +use libc::{time_t, suseconds_t, timeval}; #[repr(C)] -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)] -pub struct TimeVal { - tv_sec: time_t, - tv_usec: suseconds_t, -} +#[derive(Clone, Copy)] +pub struct TimeVal(timeval); const MICROS_PER_SEC: i64 = 1_000_000; const SECS_PER_MINUTE: i64 = 60; @@ -20,6 +17,43 @@ const MAX_SECONDS: i64 = ::std::isize::MAX as i64; const MIN_SECONDS: i64 = -MAX_SECONDS; +impl fmt::Debug for TimeVal { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("TimeVal") + .field("tv_sec", &self.tv_sec()) + .field("tv_usec", &self.tv_usec()) + .finish() + } +} + +impl cmp::PartialEq for TimeVal { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_usec must always be within [0, 1_000_000) + fn eq(&self, other: &TimeVal) -> bool { + self.tv_sec() == other.tv_sec() && self.tv_usec() == other.tv_usec() + } +} + +impl cmp::Eq for TimeVal {} + +impl cmp::Ord for TimeVal { + // The implementation of cmp is simplified by assuming that the struct is + // normalized. That is, tv_usec must always be within [0, 1_000_000) + fn cmp(&self, other: &TimeVal) -> cmp::Ordering { + if self.tv_sec() == other.tv_sec() { + self.tv_sec().cmp(&other.tv_sec()) + } else { + self.tv_usec().cmp(&other.tv_usec()) + } + } +} + +impl cmp::PartialOrd for TimeVal { + fn partial_cmp(&self, other: &TimeVal) -> Option<cmp::Ordering> { + Some(self.cmp(other)) + } +} + impl TimeVal { #[inline] pub fn zero() -> TimeVal { @@ -45,7 +79,7 @@ impl TimeVal { #[inline] pub fn seconds(seconds: i64) -> TimeVal { assert!(seconds >= MIN_SECONDS && seconds <= MAX_SECONDS, "TimeVal out of bounds; seconds={}", seconds); - TimeVal { tv_sec: seconds as time_t, tv_usec: 0 } + TimeVal(timeval {tv_sec: seconds as time_t, tv_usec: 0 }) } #[inline] @@ -61,7 +95,8 @@ impl TimeVal { pub fn microseconds(microseconds: i64) -> TimeVal { let (secs, micros) = div_mod_floor_64(microseconds, MICROS_PER_SEC); assert!(secs >= MIN_SECONDS && secs <= MAX_SECONDS, "TimeVal out of bounds"); - TimeVal { tv_sec: secs as time_t, tv_usec: micros as suseconds_t } + TimeVal(timeval {tv_sec: secs as time_t, + tv_usec: micros as suseconds_t }) } pub fn num_hours(&self) -> i64 { @@ -73,10 +108,10 @@ impl TimeVal { } pub fn num_seconds(&self) -> i64 { - if self.tv_sec < 0 && self.tv_usec > 0 { - (self.tv_sec + 1) as i64 + if self.tv_sec() < 0 && self.tv_usec() > 0 { + (self.tv_sec() + 1) as i64 } else { - self.tv_sec as i64 + self.tv_sec() as i64 } } @@ -91,12 +126,24 @@ impl TimeVal { } fn micros_mod_sec(&self) -> suseconds_t { - if self.tv_sec < 0 && self.tv_usec > 0 { - self.tv_usec - MICROS_PER_SEC as suseconds_t + if self.tv_sec() < 0 && self.tv_usec() > 0 { + self.tv_usec() - MICROS_PER_SEC as suseconds_t } else { - self.tv_usec + self.tv_usec() } } + + pub fn timeval(&self) -> timeval{ + self.0 + } + + pub fn tv_sec(&self) -> time_t { + self.0.tv_sec + } + + pub fn tv_usec(&self) -> suseconds_t { + self.0.tv_usec + } } impl ops::Neg for TimeVal { @@ -147,26 +194,26 @@ impl ops::Div<i32> for TimeVal { impl fmt::Display for TimeVal { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let (abs, sign) = if self.tv_sec < 0 { + let (abs, sign) = if self.tv_sec() < 0 { (-*self, "-") } else { (*self, "") }; - let sec = abs.tv_sec; + let sec = abs.tv_sec(); try!(write!(f, "{}", sign)); - if abs.tv_usec == 0 { - if abs.tv_sec == 1 { + if abs.tv_usec() == 0 { + if abs.tv_sec() == 1 { try!(write!(f, "{} second", sec)); } else { try!(write!(f, "{} seconds", sec)); } - } else if abs.tv_usec % 1000 == 0 { - try!(write!(f, "{}.{:03} seconds", sec, abs.tv_usec / 1000)); + } else if abs.tv_usec() % 1000 == 0 { + try!(write!(f, "{}.{:03} seconds", sec, abs.tv_usec() / 1000)); } else { - try!(write!(f, "{}.{:06} seconds", sec, abs.tv_usec)); + try!(write!(f, "{}.{:06} seconds", sec, abs.tv_usec())); } Ok(()) |