diff --git a/src/header/sys_select/mod.rs b/src/header/sys_select/mod.rs index 4aaeab6a09dac0706146b737ac0fcd303761b45d..0c5614b950aa40cfc834560b99fbf83909fc54c8 100644 --- a/src/header/sys_select/mod.rs +++ b/src/header/sys_select/mod.rs @@ -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; } }