1use rustix::time::{ 2 timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags, 3 TimerfdTimerFlags, Timespec, 4}; 5 6#[test] 7fn test_timerfd() { 8 let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); 9 10 let set = Itimerspec { 11 it_interval: Timespec { 12 tv_sec: 0, 13 tv_nsec: 0, 14 }, 15 it_value: Timespec { 16 tv_sec: 1, 17 tv_nsec: 2, 18 }, 19 }; 20 let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap(); 21 22 // Wait for the timer to expire. 23 let mut buf = [0_u8; 8]; 24 assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); 25 assert!(u64::from_ne_bytes(buf) >= 1); 26 27 let new = timerfd_gettime(&fd).unwrap(); 28 29 // The timer counts down. 30 assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); 31 assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); 32 assert!(new.it_value.tv_sec <= set.it_value.tv_sec); 33 assert!( 34 new.it_value.tv_nsec < set.it_value.tv_nsec || new.it_value.tv_sec < set.it_value.tv_sec 35 ); 36} 37 38/// Similar, but set an interval for a repeated timer. Don't check that the 39/// times are monotonic because that would race with the timer repeating. 40#[test] 41fn test_timerfd_with_interval() { 42 let fd = timerfd_create(TimerfdClockId::Monotonic, TimerfdFlags::CLOEXEC).unwrap(); 43 44 let set = Itimerspec { 45 it_interval: Timespec { 46 tv_sec: 0, 47 tv_nsec: 6, 48 }, 49 it_value: Timespec { 50 tv_sec: 1, 51 tv_nsec: 7, 52 }, 53 }; 54 let _old: Itimerspec = timerfd_settime(&fd, TimerfdTimerFlags::ABSTIME, &set).unwrap(); 55 56 // Wait for the timer to expire. 57 let mut buf = [0_u8; 8]; 58 assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); 59 assert!(u64::from_ne_bytes(buf) >= 1); 60 61 let new = timerfd_gettime(&fd).unwrap(); 62 63 assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); 64 assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); 65 66 // Wait for the timer to expire again. 67 let mut buf = [0_u8; 8]; 68 assert_eq!(rustix::io::read(&fd, &mut buf), Ok(8)); 69 assert!(u64::from_ne_bytes(buf) >= 1); 70 71 let new = timerfd_gettime(&fd).unwrap(); 72 73 assert_eq!(set.it_interval.tv_sec, new.it_interval.tv_sec); 74 assert_eq!(set.it_interval.tv_nsec, new.it_interval.tv_nsec); 75} 76