1
- use std:: ptr :: null_mut ;
1
+ use std:: mem ;
2
2
use std:: os:: unix:: io:: RawFd ;
3
- use libc:: { c_int, timeval} ;
3
+ use std:: ptr:: null_mut;
4
+ use libc:: { self , c_int} ;
4
5
use { Errno , Result } ;
5
6
use sys:: time:: TimeVal ;
6
7
7
- pub const FD_SETSIZE : RawFd = 1024 ;
8
+ pub use libc :: FD_SETSIZE ;
8
9
9
- # [ cfg ( any ( target_os = "macos" , target_os = "ios" ) ) ]
10
+ // FIXME: Change to repr(transparent) once it's stable
10
11
#[ 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 ) ;
28
13
29
14
impl FdSet {
30
15
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 )
34
19
}
35
20
36
21
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 ) } ;
39
23
}
40
24
41
25
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 ) } ;
44
27
}
45
28
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 ) }
49
31
}
50
32
51
33
pub fn clear ( & mut self ) {
52
- for bits in & mut self . bits {
53
- * bits = 0
54
- }
34
+ unsafe { libc:: FD_ZERO ( & mut self . 0 ) } ;
55
35
}
56
36
57
37
/// Finds the highest file descriptor in the set.
@@ -74,36 +54,18 @@ impl FdSet {
74
54
/// ```
75
55
///
76
56
/// [`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)
87
62
}
88
63
}
89
64
90
65
None
91
66
}
92
67
}
93
68
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
-
107
69
/// Monitors file descriptors for readiness (see [select(2)]).
108
70
///
109
71
/// Returns the total number of ready file descriptors in all sets. The sets are changed so that all
@@ -136,28 +98,28 @@ where
136
98
E : Into < Option < & ' a mut FdSet > > ,
137
99
T : Into < Option < & ' a mut TimeVal > > ,
138
100
{
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 ( ) ;
142
104
let timeout = timeout. into ( ) ;
143
105
144
106
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 ( ) )
148
110
. map ( |set| set. highest ( ) . unwrap_or ( -1 ) )
149
111
. max ( )
150
112
. unwrap_or ( -1 ) + 1
151
113
} ) ;
152
114
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 )
157
119
. unwrap_or ( null_mut ( ) ) ;
158
120
159
121
let res = unsafe {
160
- ffi :: select ( nfds, readfds, writefds, errorfds, timeout)
122
+ libc :: select ( nfds, readfds, writefds, errorfds, timeout)
161
123
} ;
162
124
163
125
Errno :: result ( res)
@@ -174,7 +136,7 @@ mod tests {
174
136
let mut fd_set = FdSet :: new ( ) ;
175
137
176
138
for i in 0 ..FD_SETSIZE {
177
- assert ! ( !fd_set. contains( i) ) ;
139
+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
178
140
}
179
141
180
142
fd_set. insert ( 7 ) ;
@@ -187,28 +149,28 @@ mod tests {
187
149
let mut fd_set = FdSet :: new ( ) ;
188
150
189
151
for i in 0 ..FD_SETSIZE {
190
- assert ! ( !fd_set. contains( i) ) ;
152
+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
191
153
}
192
154
193
155
fd_set. insert ( 7 ) ;
194
156
fd_set. remove ( 7 ) ;
195
157
196
158
for i in 0 ..FD_SETSIZE {
197
- assert ! ( !fd_set. contains( i) ) ;
159
+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
198
160
}
199
161
}
200
162
201
163
#[ test]
202
164
fn fdset_clear ( ) {
203
165
let mut fd_set = FdSet :: new ( ) ;
204
166
fd_set. insert ( 1 ) ;
205
- fd_set. insert ( FD_SETSIZE / 2 ) ;
206
- fd_set. insert ( FD_SETSIZE - 1 ) ;
167
+ fd_set. insert ( ( FD_SETSIZE / 2 ) as RawFd ) ;
168
+ fd_set. insert ( ( FD_SETSIZE - 1 ) as RawFd ) ;
207
169
208
170
fd_set. clear ( ) ;
209
171
210
172
for i in 0 ..FD_SETSIZE {
211
- assert ! ( !fd_set. contains( i) ) ;
173
+ assert ! ( !fd_set. contains( i as RawFd ) ) ;
212
174
}
213
175
}
214
176
0 commit comments