Use cbitset crate instead of custom bitset implementation in select

This commit is contained in:
lmiskiew
2019-06-13 12:31:30 +00:00
committed by jD91mZM2
parent e84ea94dd0
commit 43f1b582ae
+27 -48
View File
@@ -2,6 +2,8 @@
use core::mem;
use cbitset::BitSet;
use fs::File;
use header::errno;
use header::sys_epoll::{epoll_create1, epoll_ctl, epoll_data, epoll_event, epoll_wait, EPOLLERR,
@@ -13,45 +15,18 @@ use platform::types::*;
// fd_set is also defined in C because cbindgen is incompatible with mem::size_of booo
pub const FD_SETSIZE: usize = 1024;
type bitset = BitSet<[c_ulong; FD_SETSIZE / (8 * mem::size_of::<c_ulong>())]>;
#[repr(C)]
pub struct fd_set {
pub fds_bits: [c_ulong; FD_SETSIZE / (8 * mem::size_of::<c_ulong>())],
}
impl fd_set {
fn index(fd: c_int) -> usize {
(fd as usize) / (8 * mem::size_of::<c_ulong>())
}
fn bitmask(fd: c_int) -> c_ulong {
1 << ((fd as usize) & (8 * mem::size_of::<c_ulong>() - 1)) as c_ulong
}
fn zero(&mut self) {
for i in 0..self.fds_bits.len() {
self.fds_bits[i] = 0;
}
}
fn set(&mut self, fd: c_int) {
self.fds_bits[Self::index(fd)] |= Self::bitmask(fd);
}
fn clr(&mut self, fd: c_int) {
self.fds_bits[Self::index(fd)] &= !Self::bitmask(fd);
}
fn isset(&self, fd: c_int) -> bool {
self.fds_bits[Self::index(fd)] & Self::bitmask(fd) > 0
}
pub fds_bits: bitset,
}
pub fn select_epoll(
nfds: c_int,
mut readfds: Option<&mut fd_set>,
mut writefds: Option<&mut fd_set>,
mut exceptfds: Option<&mut fd_set>,
readfds: Option<&mut fd_set>,
writefds: Option<&mut fd_set>,
exceptfds: Option<&mut fd_set>,
timeout: Option<&mut timeval>,
) -> c_int {
if nfds < 0 || nfds > FD_SETSIZE as i32 {
@@ -67,11 +42,15 @@ pub fn select_epoll(
File::new(epfd)
};
let mut read_bitset : Option<&mut bitset> = readfds.map(|fd_set| &mut fd_set.fds_bits);
let mut write_bitset : Option<&mut bitset> = writefds.map(|fd_set| &mut fd_set.fds_bits);
let mut except_bitset : Option<&mut bitset> = exceptfds.map(|fd_set| &mut fd_set.fds_bits);
// Keep track of the number of file descriptors that do not support epoll
let mut not_epoll = 0;
for fd in 0..nfds {
if let Some(ref mut fd_set) = readfds {
if fd_set.isset(fd) {
if let Some(ref mut fd_set) = read_bitset {
if fd_set.contains(fd as usize) {
let mut event = epoll_event {
events: EPOLLIN,
data: epoll_data { fd },
@@ -84,12 +63,12 @@ pub fn select_epoll(
return -1;
}
} else {
fd_set.clr(fd);
fd_set.remove(fd as usize);
}
}
}
if let Some(ref mut fd_set) = writefds {
if fd_set.isset(fd) {
if let Some(ref mut fd_set) = write_bitset {
if fd_set.contains(fd as usize) {
let mut event = epoll_event {
events: EPOLLOUT,
data: epoll_data { fd },
@@ -102,12 +81,12 @@ pub fn select_epoll(
return -1;
}
} else {
fd_set.clr(fd);
fd_set.remove(fd as usize);
}
}
}
if let Some(ref mut fd_set) = exceptfds {
if fd_set.isset(fd) {
if let Some(ref mut fd_set) = except_bitset {
if fd_set.contains(fd as usize) {
let mut event = epoll_event {
events: EPOLLERR,
data: epoll_data { fd },
@@ -120,7 +99,7 @@ pub fn select_epoll(
return -1;
}
} else {
fd_set.clr(fd);
fd_set.remove(fd as usize);
}
}
}
@@ -154,22 +133,22 @@ pub fn select_epoll(
let event = &events[i];
let fd = unsafe { event.data.fd };
// TODO: Error status when fd does not match?
if fd >= 0 && fd <= FD_SETSIZE as c_int {
if fd >= 0 && fd < FD_SETSIZE as c_int {
if event.events & EPOLLIN > 0 {
if let Some(ref mut fd_set) = readfds {
fd_set.set(fd);
if let Some(ref mut fd_set) = read_bitset {
fd_set.insert(fd as usize);
count += 1;
}
}
if event.events & EPOLLOUT > 0 {
if let Some(ref mut fd_set) = writefds {
fd_set.set(fd);
if let Some(ref mut fd_set) = write_bitset {
fd_set.insert(fd as usize);
count += 1;
}
}
if event.events & EPOLLERR > 0 {
if let Some(ref mut fd_set) = exceptfds {
fd_set.set(fd);
if let Some(ref mut fd_set) = except_bitset {
fd_set.insert(fd as usize);
count += 1;
}
}