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 Zircon event pairs. 6 7 use {AsHandleRef, Cookied, HandleBased, Handle, HandleRef, Peered, Status}; 8 use {sys, ok}; 9 10 /// An object representing a Zircon 11 /// [event pair](https://fuchsia.googlesource.com/zircon/+/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 impl_handle_based!(EventPair); 17 impl Peered for EventPair {} 18 impl Cookied for EventPair {} 19 20 impl EventPair { 21 /// Create an event pair, a pair of objects which can signal each other. Wraps the 22 /// [zx_eventpair_create](https://fuchsia.googlesource.com/zircon/+/master/docs/syscalls/eventpair_create.md) 23 /// syscall. create() -> Result<(EventPair, EventPair), Status>24 pub fn create() -> Result<(EventPair, EventPair), Status> { 25 let mut out0 = 0; 26 let mut out1 = 0; 27 let options = 0; 28 let status = unsafe { sys::zx_eventpair_create(options, &mut out0, &mut out1) }; 29 ok(status)?; 30 unsafe { 31 Ok(( 32 Self::from(Handle::from_raw(out0)), 33 Self::from(Handle::from_raw(out1)) 34 )) 35 } 36 } 37 } 38 39 #[cfg(test)] 40 mod tests { 41 use super::*; 42 use {DurationNum, Signals}; 43 44 #[test] wait_and_signal_peer()45 fn wait_and_signal_peer() { 46 let (p1, p2) = EventPair::create().unwrap(); 47 let eighty_ms = 80.millis(); 48 49 // Waiting on one without setting any signal should time out. 50 assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()), Err(Status::TIMED_OUT)); 51 52 // If we set a signal, we should be able to wait for it. 53 assert!(p1.signal_peer(Signals::NONE, Signals::USER_0).is_ok()); 54 assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()).unwrap(), 55 Signals::USER_0); 56 57 // Should still work, signals aren't automatically cleared. 58 assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()).unwrap(), 59 Signals::USER_0); 60 61 // Now clear it, and waiting should time out again. 62 assert!(p1.signal_peer(Signals::USER_0, Signals::NONE).is_ok()); 63 assert_eq!(p2.wait_handle(Signals::USER_0, eighty_ms.after_now()), Err(Status::TIMED_OUT)); 64 } 65 } 66