diff options
author | Dylan Reid <dgreid@chromium.org> | 2018-09-07 22:36:55 +0000 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-17 21:34:42 -0700 |
commit | 407c3151d81441f9ab4b64243b62b7692090a4a8 (patch) | |
tree | d86f2ae6c802774ddaa30910957b84df7ee229e6 /sys_util | |
parent | 32e17bc0b7ddd0cfa2ace015f38bce8375e43af2 (diff) | |
download | crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar.gz crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar.bz2 crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar.lz crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar.xz crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.tar.zst crosvm-407c3151d81441f9ab4b64243b62b7692090a4a8.zip |
sys_util: timerfd: Add ability to check if the timer is armed
This allows users to only arm timers if not already armed. Signed-off-by: Dylan Reid <dgreid@chromium.org> Change-Id: I8d7c6a7643a2ae2ce4b5679107bfd2be6e4adf3a Reviewed-on: https://chromium-review.googlesource.com/1214442 Reviewed-by: Chirantan Ekbote <chirantan@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'sys_util')
-rw-r--r-- | sys_util/src/timerfd.rs | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sys_util/src/timerfd.rs b/sys_util/src/timerfd.rs index 7d2c76a..6effd22 100644 --- a/sys_util/src/timerfd.rs +++ b/sys_util/src/timerfd.rs @@ -8,7 +8,7 @@ use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use std::ptr; use std::time::Duration; -use libc::{self, CLOCK_MONOTONIC, TFD_CLOEXEC, timerfd_create, timerfd_settime}; +use libc::{self, CLOCK_MONOTONIC, TFD_CLOEXEC, timerfd_create, timerfd_gettime, timerfd_settime}; use {Result, errno_result}; @@ -73,6 +73,20 @@ impl TimerFd { Ok(count) } + /// Returns `true` if the timer is currently armed. + pub fn is_armed(&self) -> Result<bool> { + // Safe because we are zero-initializing a struct with only primitive member fields. + let mut spec: libc::itimerspec = unsafe { mem::zeroed() }; + + // Safe because timerfd_gettime is trusted to only modify `spec`. + let ret = unsafe { timerfd_gettime(self.as_raw_fd(), &mut spec) }; + if ret < 0 { + return errno_result(); + } + + Ok(spec.it_value.tv_sec != 0 || spec.it_value.tv_nsec != 0) + } + /// Disarms the timer. pub fn clear(&mut self) -> Result<()> { // Safe because we are zero-initializing a struct with only primitive member fields. @@ -115,11 +129,14 @@ mod tests { #[test] fn one_shot() { let mut tfd = TimerFd::new().expect("failed to create timerfd"); + assert_eq!(tfd.is_armed().unwrap(), false); let dur = Duration::from_millis(200); let now = Instant::now(); tfd.reset(dur.clone(), None).expect("failed to arm timer"); + assert_eq!(tfd.is_armed().unwrap(), true); + let count = tfd.wait().expect("unable to wait for timer"); assert_eq!(count, 1); |