1use crate::sys::zx_wait_item_t;
6use crate::{AsHandleRef, HandleRef, MonotonicInstant, Signals, Status, sys};
7
8#[repr(C)]
15#[derive(Debug)]
16pub struct WaitItem<'a> {
17 handle: HandleRef<'a>,
19 waiting_for: Signals,
21 pending: Signals,
23}
24
25static_assertions::assert_eq_size!(WaitItem<'_>, zx_wait_item_t);
28static_assertions::assert_eq_align!(WaitItem<'_>, zx_wait_item_t);
29static_assertions::const_assert_eq!(
30 std::mem::offset_of!(WaitItem<'_>, handle),
31 std::mem::offset_of!(zx_wait_item_t, handle),
32);
33static_assertions::const_assert_eq!(
34 std::mem::offset_of!(WaitItem<'_>, waiting_for),
35 std::mem::offset_of!(zx_wait_item_t, waitfor),
36);
37static_assertions::const_assert_eq!(
38 std::mem::offset_of!(WaitItem<'_>, pending),
39 std::mem::offset_of!(zx_wait_item_t, pending),
40);
41
42impl<'a> WaitItem<'a> {
43 pub(crate) fn new(handle: HandleRef<'a>, waiting_for: Signals) -> Self {
45 let handle = unsafe { HandleRef::from_raw_handle(handle.raw_handle()) };
47 Self { handle, waiting_for, pending: Signals::empty() }
48 }
49
50 pub fn handle(&self) -> HandleRef<'a> {
52 self.handle.clone()
53 }
54
55 pub fn waiting_for(&self) -> Signals {
57 self.waiting_for
58 }
59
60 pub fn pending(&self) -> Signals {
62 self.pending
63 }
64}
65
66impl<'a> AsHandleRef for WaitItem<'a> {
67 fn as_handle_ref(&self) -> HandleRef<'a> {
68 self.handle()
69 }
70}
71
72pub fn object_wait_many(
80 items: &mut [WaitItem<'_>],
81 deadline: MonotonicInstant,
82) -> Result<bool, Status> {
83 let status = unsafe {
86 sys::zx_object_wait_many(
87 items.as_mut_ptr().cast::<zx_wait_item_t>(),
88 items.len(),
89 deadline.into_nanos(),
90 )
91 };
92 if status == sys::ZX_ERR_CANCELED {
93 return Ok(true);
94 }
95 Status::ok(status).map(|()| false)
96}
97
98#[cfg(test)]
99mod tests {
100 use super::*;
101 use crate::{Duration, Event, WaitResult};
102
103 #[test]
104 fn wait_and_signal() {
105 let event = Event::create();
106 let ten_ms = Duration::from_millis(10);
107
108 assert_eq!(
110 event.wait_one(Signals::USER_0, MonotonicInstant::after(ten_ms)),
111 WaitResult::TimedOut(Signals::empty())
112 );
113
114 assert!(event.signal(Signals::NONE, Signals::USER_0).is_ok());
116 assert_eq!(
117 event.wait_one(Signals::USER_0, MonotonicInstant::after(ten_ms)).unwrap(),
118 Signals::USER_0
119 );
120
121 assert_eq!(
123 event.wait_one(Signals::USER_0, MonotonicInstant::after(ten_ms)).unwrap(),
124 Signals::USER_0
125 );
126
127 assert!(event.signal(Signals::USER_0, Signals::NONE).is_ok());
129 assert_eq!(
130 event.wait_one(Signals::USER_0, MonotonicInstant::after(ten_ms)),
131 WaitResult::TimedOut(Signals::empty())
132 );
133 }
134
135 #[test]
136 fn wait_many_and_signal() {
137 let ten_ms = Duration::from_millis(10);
138 let e1 = Event::create();
139 let e2 = Event::create();
140
141 let mut items = [e1.wait_item(Signals::USER_0), e2.wait_item(Signals::USER_1)];
143 assert_eq!(
144 object_wait_many(&mut items[..], MonotonicInstant::after(ten_ms)),
145 Err(Status::TIMED_OUT)
146 );
147 assert_eq!(items[0].pending(), Signals::NONE);
148 assert_eq!(items[1].pending(), Signals::NONE);
149
150 assert!(e1.signal(Signals::NONE, Signals::USER_0).is_ok());
152 assert!(object_wait_many(&mut items, MonotonicInstant::after(ten_ms)).is_ok());
153 assert_eq!(items[0].pending(), Signals::USER_0);
154 assert_eq!(items[1].pending(), Signals::NONE);
155
156 assert!(e2.signal(Signals::NONE, Signals::USER_1).is_ok());
158 assert!(object_wait_many(&mut items, MonotonicInstant::after(ten_ms)).is_ok());
159 assert_eq!(items[0].pending(), Signals::USER_0);
160 assert_eq!(items[1].pending(), Signals::USER_1);
161
162 assert!(e1.signal(Signals::USER_0, Signals::NONE).is_ok());
164 assert!(e2.signal(Signals::USER_1, Signals::NONE).is_ok());
165 assert_eq!(
166 object_wait_many(&mut items, MonotonicInstant::after(ten_ms)),
167 Err(Status::TIMED_OUT)
168 );
169 assert_eq!(items[0].pending(), Signals::NONE);
170 assert_eq!(items[1].pending(), Signals::NONE);
171 }
172}