@@ -37,6 +37,10 @@ struct ConnInner<K: Key, T: Transport, H: MessageHandler<T>> {
37
37
key : K ,
38
38
state : State < H , T > ,
39
39
transport : T ,
40
+ /// Records a WouldBlock error when trying to read
41
+ ///
42
+ /// This flag is used to prevent busy looping
43
+ read_would_block : bool ,
40
44
}
41
45
42
46
impl < K : Key , T : Transport , H : MessageHandler < T > > fmt:: Debug for ConnInner < K , T , H > {
@@ -153,7 +157,10 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> ConnInner<K, T, H> {
153
157
Ok ( head) => head,
154
158
Err ( :: Error :: Io ( e) ) => match e. kind ( ) {
155
159
io:: ErrorKind :: WouldBlock |
156
- io:: ErrorKind :: Interrupted => return state,
160
+ io:: ErrorKind :: Interrupted => {
161
+ self . read_would_block = true ;
162
+ return state;
163
+ } ,
157
164
_ => {
158
165
debug ! ( "io error trying to parse {:?}" , e) ;
159
166
return State :: Closed ;
@@ -236,6 +243,30 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> ConnInner<K, T, H> {
236
243
}
237
244
}
238
245
} ,
246
+ State :: Init { interest : Next_ :: Wait , .. } => {
247
+ match self . buf . read_from ( & mut self . transport ) {
248
+ Ok ( 0 ) => {
249
+ // End-of-file; connection was closed by peer
250
+ State :: Closed
251
+ } ,
252
+ Ok ( n) => {
253
+ // Didn't expect bytes here! Close the connection.
254
+ warn ! ( "read {} bytes in State::Init with Wait interest" , n) ;
255
+ State :: Closed
256
+ } ,
257
+ Err ( e) => match e. kind ( ) {
258
+ io:: ErrorKind :: WouldBlock => {
259
+ // This is the expected case reading in this state
260
+ self . read_would_block = true ;
261
+ state
262
+ } ,
263
+ _ => {
264
+ warn ! ( "socket error reading State::Init with Wait interest: {}" , e) ;
265
+ State :: Closed
266
+ }
267
+ }
268
+ }
269
+ } ,
239
270
State :: Init { .. } => {
240
271
trace ! ( "on_readable State::{:?}" , state) ;
241
272
state
@@ -265,7 +296,10 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> ConnInner<K, T, H> {
265
296
} ,
266
297
Err ( :: Error :: Io ( e) ) => match e. kind ( ) {
267
298
io:: ErrorKind :: WouldBlock |
268
- io:: ErrorKind :: Interrupted => None ,
299
+ io:: ErrorKind :: Interrupted => {
300
+ self . read_would_block = true ;
301
+ None
302
+ } ,
269
303
_ => {
270
304
debug ! ( "io error trying to parse {:?}" , e) ;
271
305
return State :: Closed ;
@@ -459,10 +493,15 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> ConnInner<K, T, H> {
459
493
}
460
494
461
495
fn can_read_more ( & self , was_init : bool ) -> bool {
462
- match self . state {
496
+ let transport_blocked = self . transport . blocked ( ) . is_some ( ) ;
497
+ let read_would_block = self . read_would_block ;
498
+
499
+ let state_machine_ok = match self . state {
463
500
State :: Init { .. } => !was_init && !self . buf . is_empty ( ) ,
464
501
_ => !self . buf . is_empty ( )
465
- }
502
+ } ;
503
+
504
+ !transport_blocked && !read_would_block && state_machine_ok
466
505
}
467
506
468
507
fn on_error < F > ( & mut self , err : :: Error , factory : & F ) where F : MessageHandlerFactory < K , T > {
@@ -478,6 +517,8 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> ConnInner<K, T, H> {
478
517
479
518
fn on_readable < F > ( & mut self , scope : & mut Scope < F > )
480
519
where F : MessageHandlerFactory < K , T , Output =H > {
520
+ // Clear would_block flag so state is clear going into read
521
+ self . read_would_block = false ;
481
522
trace ! ( "on_readable -> {:?}" , self . state) ;
482
523
let state = mem:: replace ( & mut self . state , State :: Closed ) ;
483
524
self . state = self . read ( scope, state) ;
@@ -526,6 +567,7 @@ impl<K: Key, T: Transport, H: MessageHandler<T>> Conn<K, T, H> {
526
567
timeout_start : Some ( now) ,
527
568
} ,
528
569
transport : transport,
570
+ read_would_block : false ,
529
571
} ) )
530
572
}
531
573
0 commit comments