1 use rustix::time::{
2 timerfd_create, timerfd_gettime, timerfd_settime, Itimerspec, TimerfdClockId, TimerfdFlags,
3 TimerfdTimerFlags, Timespec,
4 };
5
6 #[test]
test_timerfd()7 fn 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]
test_timerfd_with_interval()41 fn 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