diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md
index 7e6604046..785a1b13f 100644
--- a/actix-http/CHANGES.md
+++ b/actix-http/CHANGES.md
@@ -1,6 +1,10 @@
 # Changes
 
 ## Unreleased - 2022-xx-xx
+### Fixed
+- Avoid possibility of dispatcher getting stuck while back-pressuring I/O. [#2369]
+
+[#2369]: https://github.com/actix/actix-web/pull/2369
 
 
 ## 3.2.1 - 2022-07-02
@@ -29,9 +33,9 @@
 ### Fixed
 - Revert broken fix in [#2624] that caused erroneous 500 error responses. Temporarily re-introduces [#2357] bug. [#2779]
 
+[#2624]: https://github.com/actix/actix-web/pull/2624
 [#2357]: https://github.com/actix/actix-web/issues/2357
-[#2624]: https://github.com/actix/actix-web/issues/2624
-[#2779]: https://github.com/actix/actix-web/issues/2779
+[#2779]: https://github.com/actix/actix-web/pull/2779
 
 
 ## 3.0.4 - 2022-03-09
@@ -43,14 +47,14 @@
 ### Fixed
 - Allow spaces between header name and colon when parsing responses. [#2684]
 
-[#2684]: https://github.com/actix/actix-web/issues/2684
+[#2684]: https://github.com/actix/actix-web/pull/2684
 
 
 ## 3.0.2 - 2022-03-05
 ### Fixed
 - Fix encoding camel-case header names with more than one hyphen. [#2683]
 
-[#2683]: https://github.com/actix/actix-web/issues/2683
+[#2683]: https://github.com/actix/actix-web/pull/2683
 
 
 ## 3.0.1 - 2022-03-04
diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs
index c2ddc06ba..81090667d 100644
--- a/actix-http/src/h1/dispatcher.rs
+++ b/actix-http/src/h1/dispatcher.rs
@@ -976,9 +976,11 @@ where
                 //
                 // A Request head too large to parse is only checked on `httparse::Status::Partial`.
 
-                if this.payload.is_none() {
-                    // When dispatcher has a payload the responsibility of wake up it would be shift
-                    // to h1::payload::Payload.
+                match this.payload {
+                    // When dispatcher has a payload the responsibility of wake ups is shifted to
+                    // `h1::payload::Payload` unless the payload is needing a read, in which case it
+                    // might not have access to the waker and could result in the dispatcher
+                    // getting stuck until timeout.
                     //
                     // Reason:
                     // Self wake up when there is payload would waste poll and/or result in
@@ -989,7 +991,8 @@ where
                     // read anymore. At this case read_buf could always remain beyond
                     // MAX_BUFFER_SIZE and self wake up would be busy poll dispatcher and
                     // waste resources.
-                    cx.waker().wake_by_ref();
+                    Some(ref p) if p.need_read(cx) != PayloadStatus::Read => {}
+                    _ => cx.waker().wake_by_ref(),
                 }
 
                 return Ok(false);