]> git.proxmox.com Git - rustc.git/blob - src/vendor/magenta/src/timer.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / vendor / magenta / src / timer.rs
1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 //! Type-safe bindings for Magenta timer objects.
6
7 use {ClockId, Duration, HandleBase, Handle, HandleRef, Status, Time};
8 use {sys, into_result};
9
10 /// An object representing a Magenta
11 /// [event pair](https://fuchsia.googlesource.com/magenta/+/master/docs/concepts.md#Other-IPC_Events_Event-Pairs_and-User-Signals).
12 ///
13 /// As essentially a subtype of `Handle`, it can be freely interconverted.
14 #[derive(Debug, Eq, PartialEq)]
15 pub struct Timer(Handle);
16
17 impl HandleBase for Timer {
18 fn get_ref(&self) -> HandleRef {
19 self.0.get_ref()
20 }
21
22 fn from_handle(handle: Handle) -> Self {
23 Timer(handle)
24 }
25 }
26
27 impl Timer {
28 /// Create a timer, an object that can signal when a specified point in time has been reached.
29 /// Wraps the
30 /// [mx_timer_create](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/timer_create.md)
31 /// syscall.
32 pub fn create(options: TimerOpts, clock_id: ClockId) -> Result<Timer, Status> {
33 let mut out = 0;
34 let status = unsafe { sys::mx_timer_create(options as u32, clock_id as u32, &mut out) };
35 into_result(status, || Self::from_handle(Handle(out)))
36 }
37
38 /// Starts a timer which will fire when `deadline` passes. Wraps the
39 /// [mx_timer_start](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/timer_start.md)
40 /// syscall.
41 pub fn start(&self, deadline: Time, period: Duration, slack: Duration) -> Result<(), Status> {
42 let status = unsafe { sys::mx_timer_start(self.raw_handle(), deadline, period, slack) };
43 into_result(status, || ())
44 }
45
46 /// Cancels a pending timer that was started with start(). Wraps the
47 /// [mx_timer_cancel](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/timer_cancel.md)
48 /// syscall.
49 pub fn cancel(&self) -> Result<(), Status> {
50 let status = unsafe { sys::mx_timer_cancel(self.raw_handle()) };
51 into_result(status, || ())
52 }
53 }
54
55 /// Options for creating a timer.
56 #[repr(u32)]
57 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
58 pub enum TimerOpts {
59 /// Default options.
60 Default = 0,
61 }
62
63 impl Default for TimerOpts {
64 fn default() -> Self {
65 TimerOpts::Default
66 }
67 }
68
69 #[cfg(test)]
70 mod tests {
71 use super::*;
72 use {Duration, MX_SIGNAL_LAST_HANDLE, MX_TIMER_SIGNALED};
73 use deadline_after;
74
75 #[test]
76 fn create_timer_invalid_clock() {
77 assert_eq!(Timer::create(TimerOpts::Default, ClockId::UTC).unwrap_err(), Status::ErrInvalidArgs);
78 assert_eq!(Timer::create(TimerOpts::Default, ClockId::Thread), Err(Status::ErrInvalidArgs));
79 }
80
81 #[test]
82 fn timer_basic() {
83 let ten_ms: Duration = 10_000_000;
84 let twenty_ms: Duration = 20_000_000;
85
86 // Create a timer
87 let timer = Timer::create(TimerOpts::Default, ClockId::Monotonic).unwrap();
88
89 // Should not signal yet.
90 assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
91
92 // Start it, and soon it should signal.
93 assert_eq!(timer.start(ten_ms, 0, 0), Ok(()));
94 assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(twenty_ms)).unwrap(),
95 MX_TIMER_SIGNALED | MX_SIGNAL_LAST_HANDLE);
96
97 // Cancel it, and it should stop signalling.
98 assert_eq!(timer.cancel(), Ok(()));
99 assert_eq!(timer.wait(MX_TIMER_SIGNALED, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
100 }
101 }