dope_core/platform/
poll.rs1use std::os::fd;
2
3use dope_sys::io::{poll, poll::Poll as _};
4use o3::alloc::{self, VecExt};
5
6use crate::{Backend, Errno};
7
8pub struct Set<'fd> {
10 entries: Vec<poll::Entry<'fd>>,
11}
12
13impl<'fd> Set<'fd> {
14 pub fn try_new(
15 first: impl Iterator<Item = fd::BorrowedFd<'fd>>,
16 second: impl Iterator<Item = fd::BorrowedFd<'fd>>,
17 ) -> Result<Self, alloc::Error> {
18 let sources = first.chain(second);
19 let mut entries = Vec::try_new(sources.size_hint().0)?;
20 for source in sources {
21 alloc::Vacant::try_new(&mut entries)?.insert(poll::Entry::readable(source));
22 }
23 if poll::nfds_t::try_from(entries.len()).is_err() {
24 return Err(alloc::Error::Overflow);
25 }
26 Ok(Self { entries })
27 }
28
29 pub fn poll(&mut self, timeout: i32) -> Result<Option<Ready<'_, 'fd>>, Errno> {
31 if Backend::wait::<_, Errno>(self, timeout)?.count() == 0 {
32 return Ok(None);
33 }
34 Ok(self
35 .entries
36 .iter_mut()
37 .enumerate()
38 .find_map(|(index, entry)| entry.is_ready().then_some(Ready { index, entry })))
39 }
40}
41
42pub struct Ready<'set, 'fd> {
44 index: usize,
45 entry: &'set mut poll::Entry<'fd>,
46}
47
48impl Ready<'_, '_> {
49 pub const fn index(&self) -> usize {
50 self.index
51 }
52
53 pub fn retire(self) {
55 self.entry.retire();
56 }
57}
58
59unsafe impl<'fd> poll::raw::Entries<'fd> for Set<'fd> {
62 const MAX: usize = poll::MAX_ENTRIES;
63 fn entries(&mut self) -> &mut [poll::Entry<'fd>] {
64 &mut self.entries
65 }
66}