use crate::{sys, HandleRef, MonotonicInstant, Signals, Status};
#[repr(C)]
#[derive(Debug)]
pub struct WaitItem<'a> {
pub handle: HandleRef<'a>,
pub waitfor: Signals,
pub pending: Signals,
}
pub fn object_wait_many(
items: &mut [WaitItem<'_>],
deadline: MonotonicInstant,
) -> Result<bool, Status> {
let items_ptr = items.as_mut_ptr().cast::<sys::zx_wait_item_t>();
let status = unsafe { sys::zx_object_wait_many(items_ptr, items.len(), deadline.into_nanos()) };
if status == sys::ZX_ERR_CANCELED {
return Ok(true);
}
Status::ok(status).map(|()| false)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{AsHandleRef, Duration, Event};
#[test]
fn wait_and_signal() {
let event = Event::create();
let ten_ms = Duration::from_millis(10);
assert_eq!(
event.wait_handle(Signals::USER_0, MonotonicInstant::after(ten_ms)),
Err(Status::TIMED_OUT)
);
assert!(event.signal_handle(Signals::NONE, Signals::USER_0).is_ok());
assert_eq!(
event.wait_handle(Signals::USER_0, MonotonicInstant::after(ten_ms)).unwrap(),
Signals::USER_0
);
assert_eq!(
event.wait_handle(Signals::USER_0, MonotonicInstant::after(ten_ms)).unwrap(),
Signals::USER_0
);
assert!(event.signal_handle(Signals::USER_0, Signals::NONE).is_ok());
assert_eq!(
event.wait_handle(Signals::USER_0, MonotonicInstant::after(ten_ms)),
Err(Status::TIMED_OUT)
);
}
#[test]
fn wait_many_and_signal() {
let ten_ms = Duration::from_millis(10);
let e1 = Event::create();
let e2 = Event::create();
let mut items = vec![
WaitItem {
handle: e1.as_handle_ref(),
waitfor: Signals::USER_0,
pending: Signals::NONE,
},
WaitItem {
handle: e2.as_handle_ref(),
waitfor: Signals::USER_1,
pending: Signals::NONE,
},
];
assert_eq!(
object_wait_many(&mut items, MonotonicInstant::after(ten_ms)),
Err(Status::TIMED_OUT)
);
assert_eq!(items[0].pending, Signals::NONE);
assert_eq!(items[1].pending, Signals::NONE);
assert!(e1.signal_handle(Signals::NONE, Signals::USER_0).is_ok());
assert!(object_wait_many(&mut items, MonotonicInstant::after(ten_ms)).is_ok());
assert_eq!(items[0].pending, Signals::USER_0);
assert_eq!(items[1].pending, Signals::NONE);
assert!(e2.signal_handle(Signals::NONE, Signals::USER_1).is_ok());
assert!(object_wait_many(&mut items, MonotonicInstant::after(ten_ms)).is_ok());
assert_eq!(items[0].pending, Signals::USER_0);
assert_eq!(items[1].pending, Signals::USER_1);
assert!(e1.signal_handle(Signals::USER_0, Signals::NONE).is_ok());
assert!(e2.signal_handle(Signals::USER_1, Signals::NONE).is_ok());
assert_eq!(
object_wait_many(&mut items, MonotonicInstant::after(ten_ms)),
Err(Status::TIMED_OUT)
);
assert_eq!(items[0].pending, Signals::NONE);
assert_eq!(items[1].pending, Signals::NONE);
}
}