@@ -122,10 +122,11 @@ impl Client {
122
122
// fds are set to nonblocking and combined with `pselect`
123
123
// internally.
124
124
//
125
- // Here we try to be compatible with both strategies. We
126
- // unconditionally expect the file descriptor to be in nonblocking
127
- // mode and if it happens to be in blocking mode then most of this
128
- // won't end up actually being necessary!
125
+ // Here we try to be compatible with both strategies. We optimistically
126
+ // try to read from the file descriptor which then may block, return
127
+ // a token or indicate that polling is needed.
128
+ // Blocking reads (if possible) allows the kernel to be more selective
129
+ // about which readers to wake up when a token is written to the pipe.
129
130
//
130
131
// We use `poll` here to block this thread waiting for read
131
132
// readiness, and then afterwards we perform the `read` itself. If
@@ -139,17 +140,6 @@ impl Client {
139
140
fd. fd = self . read . as_raw_fd ( ) ;
140
141
fd. events = libc:: POLLIN ;
141
142
loop {
142
- fd. revents = 0 ;
143
- if libc:: poll ( & mut fd, 1 , -1 ) == -1 {
144
- let e = io:: Error :: last_os_error ( ) ;
145
- match e. kind ( ) {
146
- io:: ErrorKind :: Interrupted => return Ok ( None ) ,
147
- _ => return Err ( e) ,
148
- }
149
- }
150
- if fd. revents == 0 {
151
- continue ;
152
- }
153
143
let mut buf = [ 0 ] ;
154
144
match ( & self . read ) . read ( & mut buf) {
155
145
Ok ( 1 ) => return Ok ( Some ( Acquired { byte : buf[ 0 ] } ) ) ,
@@ -160,10 +150,25 @@ impl Client {
160
150
) )
161
151
}
162
152
Err ( e) => match e. kind ( ) {
163
- io:: ErrorKind :: WouldBlock | io:: ErrorKind :: Interrupted => return Ok ( None ) ,
153
+ io:: ErrorKind :: WouldBlock => { /* fall through to polling */ }
154
+ io:: ErrorKind :: Interrupted => return Ok ( None ) ,
164
155
_ => return Err ( e) ,
165
156
} ,
166
157
}
158
+
159
+ loop {
160
+ fd. revents = 0 ;
161
+ if libc:: poll ( & mut fd, 1 , -1 ) == -1 {
162
+ let e = io:: Error :: last_os_error ( ) ;
163
+ return match e. kind ( ) {
164
+ io:: ErrorKind :: Interrupted => Ok ( None ) ,
165
+ _ => Err ( e) ,
166
+ } ;
167
+ }
168
+ if fd. revents != 0 {
169
+ break ;
170
+ }
171
+ }
167
172
}
168
173
}
169
174
}
0 commit comments