@@ -171,8 +171,13 @@ where
171171 for _ in 0 ..16 {
172172 let _ = self . poll_read ( cx) ?;
173173 let _ = self . poll_write ( cx) ?;
174- let _ = self . poll_flush ( cx) ?;
174+ let conn_ready = self . poll_flush ( cx) ?. is_ready ( ) ;
175175
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;
176181 // This could happen if reading paused before blocking on IO,
177182 // such as getting to the end of a framed message, but then
178183 // writing/flushing set the state back to Init. In that case,
@@ -181,7 +186,10 @@ where
181186 //
182187 // Using this instead of task::current() and notify() inside
183188 // 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) {
185193 //break;
186194 return Poll :: Ready ( Ok ( ( ) ) ) ;
187195 }
@@ -433,6 +441,11 @@ where
433441 self . conn . close_write ( ) ;
434442 }
435443
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+
436449 fn is_done ( & self ) -> bool {
437450 if self . is_closing {
438451 return true ;
0 commit comments