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.
5 //! Type-safe bindings for Magenta timer objects.
7 use {ClockId, Duration, HandleBase, Handle, HandleRef, Status, Time}
;
8 use {sys, into_result}
;
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).
13 /// As essentially a subtype of `Handle`, it can be freely interconverted.
14 #[derive(Debug, Eq, PartialEq)]
15 pub struct Timer(Handle
);
17 impl HandleBase
for Timer
{
18 fn get_ref(&self) -> HandleRef
{
22 fn from_handle(handle
: Handle
) -> Self {
28 /// Create a timer, an object that can signal when a specified point in time has been reached.
30 /// [mx_timer_create](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/timer_create.md)
32 pub fn create(options
: TimerOpts
, clock_id
: ClockId
) -> Result
<Timer
, Status
> {
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
)))
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)
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
, || ())
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)
49 pub fn cancel(&self) -> Result
<(), Status
> {
50 let status
= unsafe { sys::mx_timer_cancel(self.raw_handle()) }
;
51 into_result(status
, || ())
55 /// Options for creating a timer.
57 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
63 impl Default
for TimerOpts
{
64 fn default() -> Self {
72 use {Duration, MX_SIGNAL_LAST_HANDLE, MX_TIMER_SIGNALED}
;
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
));
83 let ten_ms
: Duration
= 10_000_000;
84 let twenty_ms
: Duration
= 20_000_000;
87 let timer
= Timer
::create(TimerOpts
::Default
, ClockId
::Monotonic
).unwrap();
89 // Should not signal yet.
90 assert_eq
!(timer
.wait(MX_TIMER_SIGNALED
, deadline_after(ten_ms
)), Err(Status
::ErrTimedOut
));
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
);
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
));