1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use {AsHandleRef, ClockId, Duration, HandleBased, Handle, HandleRef, Status, Time};
use {sys, into_result};
#[derive(Debug, Eq, PartialEq)]
pub struct Timer(Handle);
impl_handle_based!(Timer);
impl Timer {
pub fn create(options: TimerOpts, clock_id: ClockId) -> Result<Timer, Status> {
let mut out = 0;
let status = unsafe { sys::mx_timer_create(options as u32, clock_id as u32, &mut out) };
into_result(status, || Self::from(Handle(out)))
}
pub fn start(&self, deadline: Time, period: Duration, slack: Duration) -> Result<(), Status> {
let status = unsafe { sys::mx_timer_start(self.raw_handle(), deadline, period, slack) };
into_result(status, || ())
}
pub fn set(&self, deadline: Time, slack: Duration) -> Result<(), Status> {
let status = unsafe { sys::mx_timer_set(self.raw_handle(), deadline, slack) };
into_result(status, || ())
}
pub fn cancel(&self) -> Result<(), Status> {
let status = unsafe { sys::mx_timer_cancel(self.raw_handle()) };
into_result(status, || ())
}
}
#[repr(u32)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum TimerOpts {
Default = 0,
}
impl Default for TimerOpts {
fn default() -> Self {
TimerOpts::Default
}
}
#[cfg(test)]
mod tests {
use super::*;
use {Duration, MX_SIGNAL_LAST_HANDLE, MX_TIMER_SIGNALED};
use deadline_after;
#[test]
fn create_timer_invalid_clock() {
assert_eq!(Timer::create(TimerOpts::Default, ClockId::UTC).unwrap_err(), Status::ErrInvalidArgs);
assert_eq!(Timer::create(TimerOpts::Default, ClockId::Thread), Err(Status::ErrInvalidArgs));
}
#[test]
fn timer_deprecated_start() {
let ten_ms: Duration = 10_000_000;
let twenty_ms: Duration = 20_000_000;
let timer = Timer::create(TimerOpts::Default, ClockId::Monotonic).unwrap();
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
assert_eq!(timer.start(ten_ms, 0, 0), Ok(()));
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(twenty_ms)).unwrap(),
MX_TIMER_SIGNALED | MX_SIGNAL_LAST_HANDLE);
assert_eq!(timer.cancel(), Ok(()));
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
}
#[test]
fn timer_basic() {
let ten_ms: Duration = 10_000_000;
let twenty_ms: Duration = 20_000_000;
let timer = Timer::create(TimerOpts::Default, ClockId::Monotonic).unwrap();
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
assert_eq!(timer.set(ten_ms, 0), Ok(()));
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(twenty_ms)).unwrap(),
MX_TIMER_SIGNALED | MX_SIGNAL_LAST_HANDLE);
assert_eq!(timer.cancel(), Ok(()));
assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
}
}