]> git.proxmox.com Git - rustc.git/blob - src/vendor/magenta/src/eventpair.rs
New upstream version 1.22.1+dfsg1
[rustc.git] / src / vendor / magenta / src / eventpair.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 event pairs.
6
7 use {Cookied, HandleBase, Handle, HandleRef, Peered, Status};
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 EventPair(Handle);
16
17 impl HandleBase for EventPair {
18 fn get_ref(&self) -> HandleRef {
19 self.0.get_ref()
20 }
21
22 fn from_handle(handle: Handle) -> Self {
23 EventPair(handle)
24 }
25 }
26
27 impl Peered for EventPair {
28 }
29
30 impl Cookied for EventPair {
31 }
32
33 impl EventPair {
34 /// Create an event pair, a pair of objects which can signal each other. Wraps the
35 /// [mx_eventpair_create](https://fuchsia.googlesource.com/magenta/+/master/docs/syscalls/eventpair_create.md)
36 /// syscall.
37 pub fn create(options: EventPairOpts) -> Result<(EventPair, EventPair), Status> {
38 let mut out0 = 0;
39 let mut out1 = 0;
40 let status = unsafe { sys::mx_eventpair_create(options as u32, &mut out0, &mut out1) };
41 into_result(status, ||
42 (Self::from_handle(Handle(out0)),
43 Self::from_handle(Handle(out1))))
44 }
45 }
46
47 /// Options for creating an event pair.
48 #[repr(u32)]
49 #[derive(Debug, Copy, Clone, Eq, PartialEq)]
50 pub enum EventPairOpts {
51 /// Default options.
52 Default = 0,
53 }
54
55 impl Default for EventPairOpts {
56 fn default() -> Self {
57 EventPairOpts::Default
58 }
59 }
60
61 #[cfg(test)]
62 mod tests {
63 use super::*;
64 use {Duration, MX_SIGNAL_LAST_HANDLE, MX_SIGNAL_NONE, MX_USER_SIGNAL_0};
65 use deadline_after;
66
67 #[test]
68 fn wait_and_signal_peer() {
69 let (p1, p2) = EventPair::create(EventPairOpts::Default).unwrap();
70 let ten_ms: Duration = 10_000_000;
71
72 // Waiting on one without setting any signal should time out.
73 assert_eq!(p2.wait(MX_USER_SIGNAL_0, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
74
75 // If we set a signal, we should be able to wait for it.
76 assert!(p1.signal_peer(MX_SIGNAL_NONE, MX_USER_SIGNAL_0).is_ok());
77 assert_eq!(p2.wait(MX_USER_SIGNAL_0, deadline_after(ten_ms)).unwrap(),
78 MX_USER_SIGNAL_0 | MX_SIGNAL_LAST_HANDLE);
79
80 // Should still work, signals aren't automatically cleared.
81 assert_eq!(p2.wait(MX_USER_SIGNAL_0, deadline_after(ten_ms)).unwrap(),
82 MX_USER_SIGNAL_0 | MX_SIGNAL_LAST_HANDLE);
83
84 // Now clear it, and waiting should time out again.
85 assert!(p1.signal_peer(MX_USER_SIGNAL_0, MX_SIGNAL_NONE).is_ok());
86 assert_eq!(p2.wait(MX_USER_SIGNAL_0, deadline_after(ten_ms)), Err(Status::ErrTimedOut));
87 }
88 }