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