summaryrefslogtreecommitdiffstats
path: root/third_party/rust/fuchsia-zircon/src/eventpair.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/fuchsia-zircon/src/eventpair.rs')
-rw-r--r--third_party/rust/fuchsia-zircon/src/eventpair.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/third_party/rust/fuchsia-zircon/src/eventpair.rs b/third_party/rust/fuchsia-zircon/src/eventpair.rs
new file mode 100644
index 0000000000..6f2d29806d
--- /dev/null
+++ b/third_party/rust/fuchsia-zircon/src/eventpair.rs
@@ -0,0 +1,65 @@
+// Copyright 2016 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+//! Type-safe bindings for Zircon event pairs.
+
+use {AsHandleRef, Cookied, HandleBased, Handle, HandleRef, Peered, Status};
+use {sys, ok};
+
+/// An object representing a Zircon
+/// [event pair](https://fuchsia.googlesource.com/zircon/+/master/docs/concepts.md#Other-IPC_Events_Event-Pairs_and-User-Signals).
+///
+/// As essentially a subtype of `Handle`, it can be freely interconverted.
+#[derive(Debug, Eq, PartialEq)]
+pub struct EventPair(Handle);
+impl_handle_based!(EventPair);
+impl Peered for EventPair {}
+impl Cookied for EventPair {}
+
+impl EventPair {
+ /// Create an event pair, a pair of objects which can signal each other. Wraps the
+ /// [zx_eventpair_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/eventpair_create.md)
+ /// syscall.
+ pub fn create() -> Result<(EventPair, EventPair), Status> {
+ let mut out0 = 0;
+ let mut out1 = 0;
+ let options = 0;
+ let status = unsafe { sys::zx_eventpair_create(options, &mut out0, &mut out1) };
+ ok(status)?;
+ unsafe {
+ Ok((
+ Self::from(Handle::from_raw(out0)),
+ Self::from(Handle::from_raw(out1))
+ ))
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use {DurationNum, Signals};
+
+ #[test]
+ fn wait_and_signal_peer() {
+ let (p1, p2) = EventPair::create().unwrap();
+ let eighty_ms = 80.millis();
+
+ // Waiting on one without setting any signal should time out.
+ assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()), Err(Status::TIMED_OUT));
+
+ // If we set a signal, we should be able to wait for it.
+ assert!(p1.signal_peer(Signals::NONE, Signals::USER_0).is_ok());
+ assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()).unwrap(),
+ Signals::USER_0);
+
+ // Should still work, signals aren't automatically cleared.
+ assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()).unwrap(),
+ Signals::USER_0);
+
+ // Now clear it, and waiting should time out again.
+ assert!(p1.signal_peer(Signals::USER_0, Signals::NONE).is_ok());
+ assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()), Err(Status::TIMED_OUT));
+ }
+}