From bef6ab45ef3d0205a34cbb6a672042dd233f05d0 Mon Sep 17 00:00:00 2001 From: Thales Fragoso Date: Thu, 19 Aug 2021 16:21:28 -0300 Subject: [PATCH] Avoid possibility of dispatcher getting stuck while backpressuring io --- actix-http/CHANGES.md | 3 ++- actix-http/src/h1/dispatcher.rs | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 65206cf9a..bbe81253b 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -9,12 +9,13 @@ * Remove slice creation pointing to potential uninitialized data on h1 encoder. [#2364] * Remove `Into` bound on `Encoder` body types. [#2375] * Fix quality parse error in Accept-Encoding header. [#2344] +* Avoid possibility of dispatcher getting stuck while backpressuring io. [#2369] [#2364]: https://github.com/actix/actix-web/pull/2364 [#2375]: https://github.com/actix/actix-web/pull/2375 [#2344]: https://github.com/actix/actix-web/pull/2344 [#2377]: https://github.com/actix/actix-web/pull/2377 - +[#2369]: https://github.com/actix/actix-web/pull/2369 ## 3.0.0-beta.8 - 2021-08-09 ### Fixed diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index aef765b89..0ca4cb69b 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -842,10 +842,13 @@ where A Request head too large to parse is only checked on httparse::Status::Partial condition. */ - if this.payload.is_none() { + match this.payload { /* When dispatcher has a payload the responsibility of wake up it would be shift to h1::payload::Payload. + Unless the payload is ready to 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 @@ -857,9 +860,9 @@ where At this case read_buf could always remain beyond MAX_BUFFER_SIZE and self wake up would be busy poll dispatcher and waste resource. - */ - cx.waker().wake_by_ref(); + Some(ref p) if p.need_read(cx) != PayloadStatus::Read => {} + _ => cx.waker().wake_by_ref(), } return Ok(false);