1- use std:: ptr :: null_mut ;
1+ use std:: mem ;
22use std:: os:: unix:: io:: RawFd ;
3- use libc:: { c_int, timeval} ;
3+ use std:: ptr:: null_mut;
4+ use libc:: { self , c_int} ;
45use { Errno , Result } ;
56use 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
2914impl 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)
@@ -166,6 +128,7 @@ where
166128#[ cfg( test) ]
167129mod tests {
168130 use super :: * ;
131+ use std:: os:: unix:: io:: RawFd ;
169132 use sys:: time:: { TimeVal , TimeValLike } ;
170133 use unistd:: { write, pipe} ;
171134
@@ -174,7 +137,7 @@ mod tests {
174137 let mut fd_set = FdSet :: new ( ) ;
175138
176139 for i in 0 ..FD_SETSIZE {
177- assert ! ( !fd_set. contains( i) ) ;
140+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
178141 }
179142
180143 fd_set. insert ( 7 ) ;
@@ -187,28 +150,28 @@ mod tests {
187150 let mut fd_set = FdSet :: new ( ) ;
188151
189152 for i in 0 ..FD_SETSIZE {
190- assert ! ( !fd_set. contains( i) ) ;
153+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
191154 }
192155
193156 fd_set. insert ( 7 ) ;
194157 fd_set. remove ( 7 ) ;
195158
196159 for i in 0 ..FD_SETSIZE {
197- assert ! ( !fd_set. contains( i) ) ;
160+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
198161 }
199162 }
200163
201164 #[ test]
202165 fn fdset_clear ( ) {
203166 let mut fd_set = FdSet :: new ( ) ;
204167 fd_set. insert ( 1 ) ;
205- fd_set. insert ( FD_SETSIZE / 2 ) ;
206- fd_set. insert ( FD_SETSIZE - 1 ) ;
168+ fd_set. insert ( ( FD_SETSIZE / 2 ) as RawFd ) ;
169+ fd_set. insert ( ( FD_SETSIZE - 1 ) as RawFd ) ;
207170
208171 fd_set. clear ( ) ;
209172
210173 for i in 0 ..FD_SETSIZE {
211- assert ! ( !fd_set. contains( i) ) ;
174+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
212175 }
213176 }
214177
0 commit comments