@@ -171,8 +171,13 @@ where
171
171
for _ in 0 ..16 {
172
172
let _ = self . poll_read ( cx) ?;
173
173
let _ = self . poll_write ( cx) ?;
174
- let _ = self . poll_flush ( cx) ?;
174
+ let conn_ready = self . poll_flush ( cx) ?. is_ready ( ) ;
175
175
176
+ // If we can write more body and the connection is ready, we should
177
+ // write again. If we return `Ready(Ok(())` here, we will yield
178
+ // without a guaranteed wakeup from the write side of the connection.
179
+ // This would lead to a deadlock if we also don't expect reads.
180
+ let wants_write_again = self . can_write_again ( ) && conn_ready;
176
181
// This could happen if reading paused before blocking on IO,
177
182
// such as getting to the end of a framed message, but then
178
183
// writing/flushing set the state back to Init. In that case,
@@ -181,7 +186,10 @@ where
181
186
//
182
187
// Using this instead of task::current() and notify() inside
183
188
// the Conn is noticeably faster in pipelined benchmarks.
184
- if !self . conn . wants_read_again ( ) {
189
+ let wants_read_again = self . conn . wants_read_again ( ) ;
190
+ // If we cannot write or read again, we yield and rely on the
191
+ // wakeup from the connection futures.
192
+ if !( wants_write_again || wants_read_again) {
185
193
//break;
186
194
return Poll :: Ready ( Ok ( ( ) ) ) ;
187
195
}
@@ -433,6 +441,11 @@ where
433
441
self . conn . close_write ( ) ;
434
442
}
435
443
444
+ /// If there is pending data in body_rx, we can make progress writing if the connection is ready.
445
+ fn can_write_again ( & mut self ) -> bool {
446
+ self . body_rx . is_some ( )
447
+ }
448
+
436
449
fn is_done ( & self ) -> bool {
437
450
if self . is_closing {
438
451
return true ;
0 commit comments