Skip to content

Commit 4c0067d

Browse files
committed
Replace ffi declarations for select
1 parent 4858f7a commit 4c0067d

File tree

1 file changed

+36
-74
lines changed

1 file changed

+36
-74
lines changed

src/sys/select.rs

Lines changed: 36 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,37 @@
1-
use std::ptr::null_mut;
1+
use std::mem;
22
use std::os::unix::io::RawFd;
3-
use libc::{c_int, timeval};
3+
use std::ptr::null_mut;
4+
use libc::{self, c_int};
45
use {Errno, Result};
56
use sys::time::TimeVal;
67

7-
pub const FD_SETSIZE: RawFd = 1024;
8+
pub use libc::FD_SETSIZE;
89

9-
#[cfg(any(target_os = "macos", target_os = "ios"))]
10+
// FIXME: Change to repr(transparent) once it's stable
1011
#[repr(C)]
11-
#[derive(Clone)]
12-
pub struct FdSet {
13-
bits: [i32; FD_SETSIZE as usize / 32]
14-
}
15-
16-
#[cfg(any(target_os = "macos", target_os = "ios"))]
17-
const BITS: usize = 32;
18-
19-
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
20-
#[repr(C)]
21-
#[derive(Clone)]
22-
pub struct FdSet {
23-
bits: [u64; FD_SETSIZE as usize / 64]
24-
}
25-
26-
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
27-
const BITS: usize = 64;
12+
pub struct FdSet(libc::fd_set);
2813

2914
impl FdSet {
3015
pub fn new() -> FdSet {
31-
FdSet {
32-
bits: [0; FD_SETSIZE as usize / BITS]
33-
}
16+
let mut fdset = unsafe { mem::uninitialized() };
17+
unsafe { libc::FD_ZERO(&mut fdset) };
18+
FdSet(fdset)
3419
}
3520

3621
pub fn insert(&mut self, fd: RawFd) {
37-
let fd = fd as usize;
38-
self.bits[fd / BITS] |= 1 << (fd % BITS);
22+
unsafe { libc::FD_SET(fd, &mut self.0) };
3923
}
4024

4125
pub fn remove(&mut self, fd: RawFd) {
42-
let fd = fd as usize;
43-
self.bits[fd / BITS] &= !(1 << (fd % BITS));
26+
unsafe { libc::FD_CLR(fd, &mut self.0) };
4427
}
4528

46-
pub fn contains(&self, fd: RawFd) -> bool {
47-
let fd = fd as usize;
48-
self.bits[fd / BITS] & (1 << (fd % BITS)) > 0
29+
pub fn contains(&mut self, fd: RawFd) -> bool {
30+
unsafe { libc::FD_ISSET(fd, &mut self.0) }
4931
}
5032

5133
pub fn clear(&mut self) {
52-
for bits in &mut self.bits {
53-
*bits = 0
54-
}
34+
unsafe { libc::FD_ZERO(&mut self.0) };
5535
}
5636

5737
/// Finds the highest file descriptor in the set.
@@ -74,36 +54,18 @@ impl FdSet {
7454
/// ```
7555
///
7656
/// [`select`]: fn.select.html
77-
pub fn highest(&self) -> Option<RawFd> {
78-
for (i, &block) in self.bits.iter().enumerate().rev() {
79-
if block != 0 {
80-
// Highest bit is located at `BITS - 1 - n.leading_zeros()`. Examples:
81-
// 0b00000001
82-
// 7 leading zeros, result should be 0 (bit at index 0 is 1)
83-
// 0b001xxxxx
84-
// 2 leading zeros, result should be 5 (bit at index 5 is 1) - x may be 0 or 1
85-
86-
return Some((i * BITS + BITS - 1 - block.leading_zeros() as usize) as RawFd);
57+
pub fn highest(&mut self) -> Option<RawFd> {
58+
for i in (0..libc::FD_SETSIZE).rev() {
59+
let i = i as RawFd;
60+
if unsafe { libc::FD_ISSET(i, self as *mut _ as *mut libc::fd_set) } {
61+
return Some(i)
8762
}
8863
}
8964

9065
None
9166
}
9267
}
9368

94-
mod ffi {
95-
use libc::{c_int, timeval};
96-
use super::FdSet;
97-
98-
extern {
99-
pub fn select(nfds: c_int,
100-
readfds: *mut FdSet,
101-
writefds: *mut FdSet,
102-
errorfds: *mut FdSet,
103-
timeout: *mut timeval) -> c_int;
104-
}
105-
}
106-
10769
/// Monitors file descriptors for readiness (see [select(2)]).
10870
///
10971
/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
@@ -136,28 +98,28 @@ where
13698
E: Into<Option<&'a mut FdSet>>,
13799
T: Into<Option<&'a mut TimeVal>>,
138100
{
139-
let readfds = readfds.into();
140-
let writefds = writefds.into();
141-
let errorfds = errorfds.into();
101+
let mut readfds = readfds.into();
102+
let mut writefds = writefds.into();
103+
let mut errorfds = errorfds.into();
142104
let timeout = timeout.into();
143105

144106
let nfds = nfds.into().unwrap_or_else(|| {
145-
readfds.iter()
146-
.chain(writefds.iter())
147-
.chain(errorfds.iter())
107+
readfds.iter_mut()
108+
.chain(writefds.iter_mut())
109+
.chain(errorfds.iter_mut())
148110
.map(|set| set.highest().unwrap_or(-1))
149111
.max()
150112
.unwrap_or(-1) + 1
151113
});
152114

153-
let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
154-
let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
155-
let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
156-
let timeout = timeout.map(|tv| tv as *mut TimeVal as *mut timeval)
115+
let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
116+
let writefds = writefds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
117+
let errorfds = errorfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
118+
let timeout = timeout.map(|tv| tv as *mut _ as *mut libc::timeval)
157119
.unwrap_or(null_mut());
158120

159121
let res = unsafe {
160-
ffi::select(nfds, readfds, writefds, errorfds, timeout)
122+
libc::select(nfds, readfds, writefds, errorfds, timeout)
161123
};
162124

163125
Errno::result(res)
@@ -174,7 +136,7 @@ mod tests {
174136
let mut fd_set = FdSet::new();
175137

176138
for i in 0..FD_SETSIZE {
177-
assert!(!fd_set.contains(i));
139+
assert!(!fd_set.contains(i as RawFd));
178140
}
179141

180142
fd_set.insert(7);
@@ -187,28 +149,28 @@ mod tests {
187149
let mut fd_set = FdSet::new();
188150

189151
for i in 0..FD_SETSIZE {
190-
assert!(!fd_set.contains(i));
152+
assert!(!fd_set.contains(i as RawFd));
191153
}
192154

193155
fd_set.insert(7);
194156
fd_set.remove(7);
195157

196158
for i in 0..FD_SETSIZE {
197-
assert!(!fd_set.contains(i));
159+
assert!(!fd_set.contains(i as RawFd));
198160
}
199161
}
200162

201163
#[test]
202164
fn fdset_clear() {
203165
let mut fd_set = FdSet::new();
204166
fd_set.insert(1);
205-
fd_set.insert(FD_SETSIZE / 2);
206-
fd_set.insert(FD_SETSIZE - 1);
167+
fd_set.insert((FD_SETSIZE / 2) as RawFd);
168+
fd_set.insert((FD_SETSIZE - 1) as RawFd);
207169

208170
fd_set.clear();
209171

210172
for i in 0..FD_SETSIZE {
211-
assert!(!fd_set.contains(i));
173+
assert!(!fd_set.contains(i as RawFd));
212174
}
213175
}
214176

0 commit comments

Comments
 (0)