1 // Copyright 2023 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::mem; 6 use std::time::Duration; 7 8 use crate::errno::errno_result; 9 use crate::errno::Error; 10 use crate::errno::Result; 11 use crate::sys::macos::kqueue::make_kevent; 12 use crate::sys::macos::kqueue::Kqueue; 13 use crate::sys::unix::clone_descriptor; 14 use crate::SafeDescriptor; 15 use crate::Timer; 16 17 impl Timer { new() -> Result<Timer>18 pub fn new() -> Result<Timer> { 19 Ok(Timer { 20 handle: SafeDescriptor::from(Kqueue::new()?), 21 interval: None, 22 }) 23 } 24 queue(&self) -> Result<Kqueue>25 fn queue(&self) -> Result<Kqueue> { 26 Ok(Kqueue::from(clone_descriptor(&self.handle)?)) 27 } 28 } 29 30 impl crate::TimerTrait for Timer { reset_oneshot(&mut self, delay: Duration) -> Result<()>31 fn reset_oneshot(&mut self, delay: Duration) -> Result<()> { 32 self.interval = None; 33 let mut event = make_kevent( 34 libc::EVFILT_TIMER, 35 libc::EV_ADD | libc::EV_ONESHOT, 36 libc::NOTE_NSECONDS, 37 ); 38 event.data = delay 39 .as_nanos() 40 .try_into() 41 .map_err(|_| Error::new(libc::EINVAL))?; 42 self.queue()?.kevent(&[event], &mut [], None)?; 43 Ok(()) 44 } 45 reset_repeating(&mut self, interval: Duration) -> Result<()>46 fn reset_repeating(&mut self, interval: Duration) -> Result<()> { 47 self.interval = Some(interval); 48 let mut event = make_kevent(libc::EVFILT_TIMER, libc::EV_ADD, libc::NOTE_NSECONDS); 49 event.data = interval 50 .as_nanos() 51 .try_into() 52 .map_err(|_| Error::new(libc::EINVAL))?; 53 self.queue()?.kevent(&[event], &mut [], None)?; 54 Ok(()) 55 } 56 wait(&mut self) -> Result<()>57 fn wait(&mut self) -> Result<()> { 58 let mut event = [make_kevent(0, 0, 0)]; 59 self.queue()?.kevent(&[], &mut event[..], None)?; 60 Ok(()) 61 } 62 mark_waited(&mut self) -> Result<bool>63 fn mark_waited(&mut self) -> Result<bool> { 64 // Timers cannot be tested without consuming the event 65 Ok(false) 66 } 67 clear(&mut self) -> Result<()>68 fn clear(&mut self) -> Result<()> { 69 let delete = make_kevent(libc::EVFILT_TIMER, libc::EV_DELETE, 0); 70 self.queue()?.kevent(&[delete], &mut [], None)?; 71 Ok(()) 72 } 73 resolution(&self) -> Result<Duration>74 fn resolution(&self) -> Result<Duration> { 75 // SAFETY: 76 // Safe because we are zero-initializing a struct with only primitive member fields. 77 let mut res: libc::timespec = unsafe { mem::zeroed() }; 78 79 // SAFETY: 80 // Safe because it only modifies a local struct and we check the return value. 81 let ret = unsafe { libc::clock_getres(libc::CLOCK_MONOTONIC, &mut res) }; 82 83 if ret != 0 { 84 return errno_result(); 85 } 86 87 Ok(Duration::new(res.tv_sec as u64, res.tv_nsec as u32)) 88 } 89 } 90