Skip to content

Commit

Permalink
Replace ffi declarations for select
Browse files Browse the repository at this point in the history
  • Loading branch information
Susurrus committed Aug 10, 2017
1 parent 6234d4b commit 8845dc2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 57 deletions.
72 changes: 20 additions & 52 deletions src/sys/select.rs
Original file line number Diff line number Diff line change
@@ -1,70 +1,38 @@
use std::ptr::null_mut;
use std::mem;
use std::os::unix::io::RawFd;
use libc::{c_int, timeval};
use std::ptr::null_mut;
use libc::{self, c_int};
use {Errno, Result};
use sys::time::TimeVal;

pub const FD_SETSIZE: RawFd = 1024;

#[cfg(any(target_os = "macos", target_os = "ios"))]
#[repr(C)]
#[derive(Clone)]
pub struct FdSet {
bits: [i32; FD_SETSIZE as usize / 32]
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
const BITS: usize = 32;
pub use libc::FD_SETSIZE;

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
// FIXME: Change to repr(transparent) once it's stable
#[repr(C)]
#[derive(Clone)]
pub struct FdSet {
bits: [u64; FD_SETSIZE as usize / 64]
}

#[cfg(not(any(target_os = "macos", target_os = "ios")))]
const BITS: usize = 64;
pub struct FdSet(libc::fd_set);

impl FdSet {
pub fn new() -> FdSet {
FdSet {
bits: [0; FD_SETSIZE as usize / BITS]
}
let mut fdset = unsafe { mem::uninitialized() };
unsafe { libc::FD_ZERO(&mut fdset) };
FdSet(fdset)
}

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

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

pub fn contains(&self, fd: RawFd) -> bool {
let fd = fd as usize;
self.bits[fd / BITS] & (1 << (fd % BITS)) > 0
// FIXME: Change to take `&self` once https://github.com/rust-lang/libc/pull/718 lands
pub fn contains(&mut self, fd: RawFd) -> bool {
unsafe { libc::FD_ISSET(fd, &mut self.0) }
}

pub fn clear(&mut self) {
for bits in &mut self.bits {
*bits = 0
}
}
}

mod ffi {
use libc::{c_int, timeval};
use super::FdSet;

extern {
pub fn select(nfds: c_int,
readfds: *mut FdSet,
writefds: *mut FdSet,
errorfds: *mut FdSet,
timeout: *mut timeval) -> c_int;
unsafe { libc::FD_ZERO(&mut self.0) };
}
}

Expand All @@ -73,14 +41,14 @@ pub fn select(nfds: c_int,
writefds: Option<&mut FdSet>,
errorfds: Option<&mut FdSet>,
timeout: Option<&mut TimeVal>) -> Result<c_int> {
let readfds = readfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let writefds = writefds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let errorfds = errorfds.map(|set| set as *mut FdSet).unwrap_or(null_mut());
let timeout = timeout.map(|tv| tv as *mut TimeVal as *mut timeval)
let readfds = readfds.map(|set| set as *mut _ as *mut libc::fd_set).unwrap_or(null_mut());
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());

let res = unsafe {
ffi::select(nfds, readfds, writefds, errorfds, timeout)
libc::select(nfds, readfds, writefds, errorfds, timeout)
};

Errno::result(res)
Expand Down
10 changes: 5 additions & 5 deletions test/sys/test_select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ fn test_fdset() {
let mut fd_set = FdSet::new();

for i in 0..FD_SETSIZE {
assert!(!fd_set.contains(i));
assert!(!fd_set.contains(i as i32));
}

fd_set.insert(7);
Expand All @@ -17,17 +17,17 @@ fn test_fdset() {
fd_set.remove(7);

for i in 0..FD_SETSIZE {
assert!(!fd_set.contains(i));
assert!(!fd_set.contains(i as i32));
}

fd_set.insert(1);
fd_set.insert(FD_SETSIZE / 2);
fd_set.insert(FD_SETSIZE - 1);
fd_set.insert(FD_SETSIZE as i32 / 2);
fd_set.insert(FD_SETSIZE as i32 - 1);

fd_set.clear();

for i in 0..FD_SETSIZE {
assert!(!fd_set.contains(i));
assert!(!fd_set.contains(i as i32));
}
}

Expand Down

0 comments on commit 8845dc2

Please sign in to comment.