diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/rust/alsa/src/poll.rs | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/alsa/src/poll.rs')
-rw-r--r-- | third_party/rust/alsa/src/poll.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/third_party/rust/alsa/src/poll.rs b/third_party/rust/alsa/src/poll.rs new file mode 100644 index 0000000000..3e9191164e --- /dev/null +++ b/third_party/rust/alsa/src/poll.rs @@ -0,0 +1,68 @@ +//! Tiny poll ffi +//! +//! A tiny wrapper around libc's poll system call. + +use libc; +use super::error::*; +use std::io; +pub use libc::pollfd; + + +bitflags! { + pub struct Flags: ::libc::c_short { + const IN = ::libc::POLLIN; + const PRI = ::libc::POLLPRI; + const OUT = ::libc::POLLOUT; + const ERR = ::libc::POLLERR; + const HUP = ::libc::POLLHUP; + const NVAL = ::libc::POLLNVAL; + } +} + +pub trait Descriptors { + fn count(&self) -> usize; + fn fill(&self, _: &mut [pollfd]) -> Result<usize>; + fn revents(&self, _: &[pollfd]) -> Result<Flags>; + + /// Wrapper around count and fill - returns an array of pollfds + fn get(&self) -> Result<Vec<pollfd>> { + let mut v = vec![pollfd { fd: 0, events: 0, revents: 0 }; self.count()]; + if self.fill(&mut v)? != v.len() { Err(Error::unsupported("did not fill the poll descriptors array")) } + else { Ok(v) } + } +} + +impl Descriptors for pollfd { + fn count(&self) -> usize { 1 } + fn fill(&self, a: &mut [pollfd]) -> Result<usize> { a[0] = *self; Ok(1) } + fn revents(&self, a: &[pollfd]) -> Result<Flags> { Ok(Flags::from_bits_truncate(a[0].revents)) } +} + +/// Wrapper around the libc poll call. +pub fn poll(fds: &mut[pollfd], timeout: i32) -> Result<usize> { + let r = unsafe { libc::poll(fds.as_mut_ptr(), fds.len() as libc::nfds_t, timeout as libc::c_int) }; + if r >= 0 { Ok(r as usize) } else { + from_code("poll", -io::Error::last_os_error().raw_os_error().unwrap()).map(|_| unreachable!()) + } +} + +/// Builds a pollfd array, polls it, and returns the poll descriptors which have non-zero revents. +pub fn poll_all<'a>(desc: &[&'a dyn Descriptors], timeout: i32) -> Result<Vec<(&'a dyn Descriptors, Flags)>> { + + let mut pollfds: Vec<pollfd> = vec!(); + let mut indices = vec!(); + for v2 in desc.iter().map(|q| q.get()) { + let v = v2?; + indices.push(pollfds.len() .. pollfds.len()+v.len()); + pollfds.extend(v); + }; + + poll(&mut pollfds, timeout)?; + + let mut res = vec!(); + for (i, r) in indices.into_iter().enumerate() { + let z = desc[i].revents(&pollfds[r])?; + if !z.is_empty() { res.push((desc[i], z)); } + } + Ok(res) +} |