@@ -122,10 +122,11 @@ impl Client {
122122 // fds are set to nonblocking and combined with `pselect`
123123 // internally.
124124 //
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.
129130 //
130131 // We use `poll` here to block this thread waiting for read
131132 // readiness, and then afterwards we perform the `read` itself. If
@@ -139,17 +140,6 @@ impl Client {
139140 fd. fd = self . read . as_raw_fd ( ) ;
140141 fd. events = libc:: POLLIN ;
141142 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- }
153143 let mut buf = [ 0 ] ;
154144 match ( & self . read ) . read ( & mut buf) {
155145 Ok ( 1 ) => return Ok ( Some ( Acquired { byte : buf[ 0 ] } ) ) ,
@@ -160,10 +150,25 @@ impl Client {
160150 ) )
161151 }
162152 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 ) ,
164155 _ => return Err ( e) ,
165156 } ,
166157 }
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+ }
167172 }
168173 }
169174 }
0 commit comments