-
Notifications
You must be signed in to change notification settings - Fork 729
Add select::FdSet::fds() method #1207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
1b5ea70
41db1bf
8b4a433
4a101ae
bcfcf82
eb5f289
1171817
e8c7961
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| use std::iter::FusedIterator; | ||
| use std::mem; | ||
| use std::ops::Range; | ||
| use std::os::unix::io::RawFd; | ||
| use std::ptr::{null, null_mut}; | ||
| use libc::{self, c_int}; | ||
|
|
@@ -30,8 +32,9 @@ impl FdSet { | |
| unsafe { libc::FD_CLR(fd, &mut self.0) }; | ||
| } | ||
|
|
||
| pub fn contains(&mut self, fd: RawFd) -> bool { | ||
| unsafe { libc::FD_ISSET(fd, &mut self.0) } | ||
| pub fn contains(&self, fd: RawFd) -> bool { | ||
| let mut copy = self.0; | ||
|
||
| unsafe { libc::FD_ISSET(fd, &mut copy) } | ||
| } | ||
|
|
||
| pub fn clear(&mut self) { | ||
|
|
@@ -58,15 +61,32 @@ impl FdSet { | |
| /// ``` | ||
| /// | ||
| /// [`select`]: fn.select.html | ||
| pub fn highest(&mut self) -> Option<RawFd> { | ||
| for i in (0..FD_SETSIZE).rev() { | ||
| let i = i as RawFd; | ||
| if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } { | ||
| return Some(i) | ||
| } | ||
| } | ||
| pub fn highest(&self) -> Option<RawFd> { | ||
| self.fds().next_back() | ||
| } | ||
|
|
||
| None | ||
| /// Returns an iterator over the file descriptors in the set. | ||
| /// | ||
| /// # Examples | ||
| /// | ||
| /// ``` | ||
| /// # extern crate nix; | ||
| /// # use nix::sys::select::FdSet; | ||
| /// # use std::os::unix::io::RawFd; | ||
| /// # fn main() { | ||
zombiezen marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// let mut set = FdSet::new(); | ||
| /// set.insert(4); | ||
| /// set.insert(9); | ||
| /// let fds: Vec<RawFd> = set.fds().collect(); | ||
| /// assert_eq!(fds, vec![4, 9]); | ||
| /// # } | ||
| /// ``` | ||
| #[inline] | ||
| pub fn fds(&self) -> Fds { | ||
|
||
| Fds { | ||
| set: self, | ||
| range: 0..FD_SETSIZE, | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -76,6 +96,46 @@ impl Default for FdSet { | |
| } | ||
| } | ||
|
|
||
| /// Iterator over `FdSet`. | ||
| #[derive(Clone, Debug)] | ||
| pub struct Fds<'a> { | ||
| set: &'a FdSet, | ||
| range: Range<usize>, | ||
| } | ||
|
|
||
| impl<'a> Iterator for Fds<'a> { | ||
| type Item = RawFd; | ||
|
|
||
| fn next(&mut self) -> Option<RawFd> { | ||
| while let Some(i) = self.range.next() { | ||
| if self.set.contains(i as RawFd) { | ||
| return Some(i as RawFd); | ||
| } | ||
| } | ||
| None | ||
| } | ||
|
|
||
| #[inline] | ||
| fn size_hint(&self) -> (usize, Option<usize>) { | ||
| let (_, upper) = self.range.size_hint(); | ||
| (0, upper) | ||
| } | ||
| } | ||
|
|
||
| impl<'a> DoubleEndedIterator for Fds<'a> { | ||
| #[inline] | ||
| fn next_back(&mut self) -> Option<RawFd> { | ||
| while let Some(i) = self.range.next_back() { | ||
| if self.set.contains(i as RawFd) { | ||
| return Some(i as RawFd); | ||
| } | ||
| } | ||
| None | ||
| } | ||
| } | ||
|
|
||
| impl<'a> FusedIterator for Fds<'a> {} | ||
|
|
||
| /// Monitors file descriptors for readiness | ||
| /// | ||
| /// Returns the total number of ready file descriptors in all sets. The sets are changed so that all | ||
|
|
@@ -100,9 +160,9 @@ impl Default for FdSet { | |
| /// | ||
| /// [`FdSet::highest`]: struct.FdSet.html#method.highest | ||
| pub fn select<'a, N, R, W, E, T>(nfds: N, | ||
| readfds: R, | ||
| writefds: W, | ||
| errorfds: E, | ||
| readfds: R, | ||
| writefds: W, | ||
| errorfds: E, | ||
| timeout: T) -> Result<c_int> | ||
| where | ||
| N: Into<Option<c_int>>, | ||
|
|
@@ -129,7 +189,7 @@ where | |
| let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); | ||
| let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut()); | ||
| let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval) | ||
| .unwrap_or(null_mut()); | ||
| .unwrap_or(null_mut()); | ||
|
|
||
| let res = unsafe { | ||
| libc::select(nfds, readfds, writefds, errorfds, timeout) | ||
|
|
@@ -168,10 +228,10 @@ where | |
| /// | ||
| /// [`FdSet::highest`]: struct.FdSet.html#method.highest | ||
| pub fn pselect<'a, N, R, W, E, T, S>(nfds: N, | ||
| readfds: R, | ||
| writefds: W, | ||
| errorfds: E, | ||
| timeout: T, | ||
| readfds: R, | ||
| writefds: W, | ||
| errorfds: E, | ||
| timeout: T, | ||
| sigmask: S) -> Result<c_int> | ||
| where | ||
| N: Into<Option<c_int>>, | ||
|
|
@@ -311,9 +371,9 @@ mod tests { | |
|
|
||
| let mut timeout = TimeVal::seconds(10); | ||
| assert_eq!(1, select(Some(fd_set.highest().unwrap() + 1), | ||
| &mut fd_set, | ||
| None, | ||
| None, | ||
| &mut fd_set, | ||
| None, | ||
| None, | ||
| &mut timeout).unwrap()); | ||
| assert!(fd_set.contains(r1)); | ||
| assert!(!fd_set.contains(r2)); | ||
|
|
@@ -331,9 +391,9 @@ mod tests { | |
|
|
||
| let mut timeout = TimeVal::seconds(10); | ||
| assert_eq!(1, select(::std::cmp::max(r1, r2) + 1, | ||
| &mut fd_set, | ||
| None, | ||
| None, | ||
| &mut fd_set, | ||
| None, | ||
| None, | ||
| &mut timeout).unwrap()); | ||
| assert!(fd_set.contains(r1)); | ||
| assert!(!fd_set.contains(r2)); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.