1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2018 The ChromiumOS Authors 2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file. 4*bb4ee6a4SAndroid Build Coastguard Worker 5*bb4ee6a4SAndroid Build Coastguard Worker use std::mem; 6*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::io::AsRawFd; 7*bb4ee6a4SAndroid Build Coastguard Worker use std::os::unix::io::RawFd; 8*bb4ee6a4SAndroid Build Coastguard Worker use std::ptr; 9*bb4ee6a4SAndroid Build Coastguard Worker use std::time::Duration; 10*bb4ee6a4SAndroid Build Coastguard Worker 11*bb4ee6a4SAndroid Build Coastguard Worker use libc::clock_getres; 12*bb4ee6a4SAndroid Build Coastguard Worker use libc::timerfd_create; 13*bb4ee6a4SAndroid Build Coastguard Worker use libc::timerfd_settime; 14*bb4ee6a4SAndroid Build Coastguard Worker use libc::CLOCK_MONOTONIC; 15*bb4ee6a4SAndroid Build Coastguard Worker use libc::EAGAIN; 16*bb4ee6a4SAndroid Build Coastguard Worker use libc::POLLIN; 17*bb4ee6a4SAndroid Build Coastguard Worker use libc::TFD_CLOEXEC; 18*bb4ee6a4SAndroid Build Coastguard Worker use libc::TFD_NONBLOCK; 19*bb4ee6a4SAndroid Build Coastguard Worker 20*bb4ee6a4SAndroid Build Coastguard Worker use super::super::errno_result; 21*bb4ee6a4SAndroid Build Coastguard Worker use super::super::Error; 22*bb4ee6a4SAndroid Build Coastguard Worker use super::super::Result; 23*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::AsRawDescriptor; 24*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::FromRawDescriptor; 25*bb4ee6a4SAndroid Build Coastguard Worker use crate::descriptor::SafeDescriptor; 26*bb4ee6a4SAndroid Build Coastguard Worker use crate::handle_eintr_errno; 27*bb4ee6a4SAndroid Build Coastguard Worker use crate::timer::Timer; 28*bb4ee6a4SAndroid Build Coastguard Worker use crate::timer::TimerTrait; 29*bb4ee6a4SAndroid Build Coastguard Worker use crate::unix::duration_to_timespec; 30*bb4ee6a4SAndroid Build Coastguard Worker 31*bb4ee6a4SAndroid Build Coastguard Worker impl AsRawFd for Timer { as_raw_fd(&self) -> RawFd32*bb4ee6a4SAndroid Build Coastguard Worker fn as_raw_fd(&self) -> RawFd { 33*bb4ee6a4SAndroid Build Coastguard Worker self.handle.as_raw_descriptor() 34*bb4ee6a4SAndroid Build Coastguard Worker } 35*bb4ee6a4SAndroid Build Coastguard Worker } 36*bb4ee6a4SAndroid Build Coastguard Worker 37*bb4ee6a4SAndroid Build Coastguard Worker impl Timer { 38*bb4ee6a4SAndroid Build Coastguard Worker /// Creates a new timerfd. The timer is initally disarmed and must be armed by calling 39*bb4ee6a4SAndroid Build Coastguard Worker /// `reset`. new() -> Result<Timer>40*bb4ee6a4SAndroid Build Coastguard Worker pub fn new() -> Result<Timer> { 41*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 42*bb4ee6a4SAndroid Build Coastguard Worker // Safe because this doesn't modify any memory and we check the return value. 43*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK) }; 44*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 45*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 46*bb4ee6a4SAndroid Build Coastguard Worker } 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard Worker Ok(Timer { 49*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 50*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we uniquely own the file descriptor. 51*bb4ee6a4SAndroid Build Coastguard Worker handle: unsafe { SafeDescriptor::from_raw_descriptor(ret) }, 52*bb4ee6a4SAndroid Build Coastguard Worker interval: None, 53*bb4ee6a4SAndroid Build Coastguard Worker }) 54*bb4ee6a4SAndroid Build Coastguard Worker } 55*bb4ee6a4SAndroid Build Coastguard Worker 56*bb4ee6a4SAndroid Build Coastguard Worker // Calls `timerfd_settime()` and stores the new value of `interval`. set_time(&mut self, dur: Option<Duration>, interval: Option<Duration>) -> Result<()>57*bb4ee6a4SAndroid Build Coastguard Worker fn set_time(&mut self, dur: Option<Duration>, interval: Option<Duration>) -> Result<()> { 58*bb4ee6a4SAndroid Build Coastguard Worker // The posix implementation of timer does not need self.interval, but we 59*bb4ee6a4SAndroid Build Coastguard Worker // save it anyways to keep a consistent interface. 60*bb4ee6a4SAndroid Build Coastguard Worker self.interval = interval; 61*bb4ee6a4SAndroid Build Coastguard Worker 62*bb4ee6a4SAndroid Build Coastguard Worker let spec = libc::itimerspec { 63*bb4ee6a4SAndroid Build Coastguard Worker it_interval: duration_to_timespec(interval.unwrap_or_default()), 64*bb4ee6a4SAndroid Build Coastguard Worker it_value: duration_to_timespec(dur.unwrap_or_default()), 65*bb4ee6a4SAndroid Build Coastguard Worker }; 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 68*bb4ee6a4SAndroid Build Coastguard Worker // Safe because this doesn't modify any memory and we check the return value. 69*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { timerfd_settime(self.as_raw_descriptor(), 0, &spec, ptr::null_mut()) }; 70*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 71*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 72*bb4ee6a4SAndroid Build Coastguard Worker } 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 75*bb4ee6a4SAndroid Build Coastguard Worker } 76*bb4ee6a4SAndroid Build Coastguard Worker } 77*bb4ee6a4SAndroid Build Coastguard Worker 78*bb4ee6a4SAndroid Build Coastguard Worker impl TimerTrait for Timer { reset_oneshot(&mut self, dur: Duration) -> Result<()>79*bb4ee6a4SAndroid Build Coastguard Worker fn reset_oneshot(&mut self, dur: Duration) -> Result<()> { 80*bb4ee6a4SAndroid Build Coastguard Worker self.set_time(Some(dur), None) 81*bb4ee6a4SAndroid Build Coastguard Worker } 82*bb4ee6a4SAndroid Build Coastguard Worker reset_repeating(&mut self, dur: Duration) -> Result<()>83*bb4ee6a4SAndroid Build Coastguard Worker fn reset_repeating(&mut self, dur: Duration) -> Result<()> { 84*bb4ee6a4SAndroid Build Coastguard Worker self.set_time(Some(dur), Some(dur)) 85*bb4ee6a4SAndroid Build Coastguard Worker } 86*bb4ee6a4SAndroid Build Coastguard Worker clear(&mut self) -> Result<()>87*bb4ee6a4SAndroid Build Coastguard Worker fn clear(&mut self) -> Result<()> { 88*bb4ee6a4SAndroid Build Coastguard Worker self.set_time(None, None) 89*bb4ee6a4SAndroid Build Coastguard Worker } 90*bb4ee6a4SAndroid Build Coastguard Worker wait(&mut self) -> Result<()>91*bb4ee6a4SAndroid Build Coastguard Worker fn wait(&mut self) -> Result<()> { 92*bb4ee6a4SAndroid Build Coastguard Worker let mut pfd = libc::pollfd { 93*bb4ee6a4SAndroid Build Coastguard Worker fd: self.as_raw_descriptor(), 94*bb4ee6a4SAndroid Build Coastguard Worker events: POLLIN, 95*bb4ee6a4SAndroid Build Coastguard Worker revents: 0, 96*bb4ee6a4SAndroid Build Coastguard Worker }; 97*bb4ee6a4SAndroid Build Coastguard Worker 98*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 99*bb4ee6a4SAndroid Build Coastguard Worker // Safe because this only modifies |pfd| and we check the return value 100*bb4ee6a4SAndroid Build Coastguard Worker let ret = handle_eintr_errno!(unsafe { 101*bb4ee6a4SAndroid Build Coastguard Worker libc::ppoll( 102*bb4ee6a4SAndroid Build Coastguard Worker &mut pfd as *mut libc::pollfd, 103*bb4ee6a4SAndroid Build Coastguard Worker 1, 104*bb4ee6a4SAndroid Build Coastguard Worker ptr::null_mut(), 105*bb4ee6a4SAndroid Build Coastguard Worker ptr::null_mut(), 106*bb4ee6a4SAndroid Build Coastguard Worker ) 107*bb4ee6a4SAndroid Build Coastguard Worker }); 108*bb4ee6a4SAndroid Build Coastguard Worker 109*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 110*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 111*bb4ee6a4SAndroid Build Coastguard Worker } 112*bb4ee6a4SAndroid Build Coastguard Worker 113*bb4ee6a4SAndroid Build Coastguard Worker // EAGAIN is a valid error in the case where another thread has called timerfd_settime 114*bb4ee6a4SAndroid Build Coastguard Worker // in between this thread calling ppoll and read. Since the ppoll returned originally 115*bb4ee6a4SAndroid Build Coastguard Worker // without any revents it means the timer did expire, so we treat this as a 116*bb4ee6a4SAndroid Build Coastguard Worker // WaitResult::Expired. 117*bb4ee6a4SAndroid Build Coastguard Worker let _ = self.mark_waited()?; 118*bb4ee6a4SAndroid Build Coastguard Worker 119*bb4ee6a4SAndroid Build Coastguard Worker Ok(()) 120*bb4ee6a4SAndroid Build Coastguard Worker } 121*bb4ee6a4SAndroid Build Coastguard Worker mark_waited(&mut self) -> Result<bool>122*bb4ee6a4SAndroid Build Coastguard Worker fn mark_waited(&mut self) -> Result<bool> { 123*bb4ee6a4SAndroid Build Coastguard Worker let mut count = 0u64; 124*bb4ee6a4SAndroid Build Coastguard Worker 125*bb4ee6a4SAndroid Build Coastguard Worker // The timerfd is in non-blocking mode, so this should return immediately. 126*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: We own the FD and provide a valid buffer we have exclusive access to. 127*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { 128*bb4ee6a4SAndroid Build Coastguard Worker libc::read( 129*bb4ee6a4SAndroid Build Coastguard Worker self.as_raw_descriptor(), 130*bb4ee6a4SAndroid Build Coastguard Worker &mut count as *mut _ as *mut libc::c_void, 131*bb4ee6a4SAndroid Build Coastguard Worker mem::size_of_val(&count), 132*bb4ee6a4SAndroid Build Coastguard Worker ) 133*bb4ee6a4SAndroid Build Coastguard Worker }; 134*bb4ee6a4SAndroid Build Coastguard Worker 135*bb4ee6a4SAndroid Build Coastguard Worker if ret < 0 { 136*bb4ee6a4SAndroid Build Coastguard Worker if Error::last().errno() == EAGAIN { 137*bb4ee6a4SAndroid Build Coastguard Worker Ok(true) 138*bb4ee6a4SAndroid Build Coastguard Worker } else { 139*bb4ee6a4SAndroid Build Coastguard Worker errno_result() 140*bb4ee6a4SAndroid Build Coastguard Worker } 141*bb4ee6a4SAndroid Build Coastguard Worker } else { 142*bb4ee6a4SAndroid Build Coastguard Worker Ok(false) 143*bb4ee6a4SAndroid Build Coastguard Worker } 144*bb4ee6a4SAndroid Build Coastguard Worker } 145*bb4ee6a4SAndroid Build Coastguard Worker resolution(&self) -> Result<Duration>146*bb4ee6a4SAndroid Build Coastguard Worker fn resolution(&self) -> Result<Duration> { 147*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 148*bb4ee6a4SAndroid Build Coastguard Worker // Safe because we are zero-initializing a struct with only primitive member fields. 149*bb4ee6a4SAndroid Build Coastguard Worker let mut res: libc::timespec = unsafe { mem::zeroed() }; 150*bb4ee6a4SAndroid Build Coastguard Worker 151*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: 152*bb4ee6a4SAndroid Build Coastguard Worker // Safe because it only modifies a local struct and we check the return value. 153*bb4ee6a4SAndroid Build Coastguard Worker let ret = unsafe { clock_getres(CLOCK_MONOTONIC, &mut res) }; 154*bb4ee6a4SAndroid Build Coastguard Worker 155*bb4ee6a4SAndroid Build Coastguard Worker if ret != 0 { 156*bb4ee6a4SAndroid Build Coastguard Worker return errno_result(); 157*bb4ee6a4SAndroid Build Coastguard Worker } 158*bb4ee6a4SAndroid Build Coastguard Worker 159*bb4ee6a4SAndroid Build Coastguard Worker Ok(Duration::new(res.tv_sec as u64, res.tv_nsec as u32)) 160*bb4ee6a4SAndroid Build Coastguard Worker } 161*bb4ee6a4SAndroid Build Coastguard Worker } 162