• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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