Use cbitset crate instead of custom bitset implementation in select
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user