60 lines
1.4 KiB
Diff
60 lines
1.4 KiB
Diff
From 78770c121e8c2315d7bdf9e66870abffdaedbe9b Mon Sep 17 00:00:00 2001
|
|
From: jingrui <jingrui@huawei.com>
|
|
Date: Thu, 20 May 2021 09:18:27 +0800
|
|
Subject: [PATCH] net/http: fix hijack hang at abortPendingRead
|
|
|
|
When concurrent many http requests which need hijack the connenction,
|
|
hijack may hang at abortPendingRead() on cr.cond.Wait().
|
|
|
|
The read can be from readRequest() from conn.serve() or
|
|
w.conn.r.startBackgroundRead(). especially in startBackgroundRead()
|
|
which always set the deadline time.Time{}.
|
|
|
|
This problem seems easy reproduce on arm.
|
|
|
|
Signed-off-by: jingrui <jingrui@huawei.com>
|
|
|
|
Conflict:NA
|
|
Reference:https://github.com/golang/go/pull/46278/commits/78770c121e8c2315d7bdf9e66870abffdaedbe9b
|
|
|
|
---
|
|
src/net/http/server.go | 22 +++++++++++++++++++---
|
|
1 file changed, 19 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/src/net/http/server.go b/src/net/http/server.go
|
|
index 4e73508973..01e7e10011 100644
|
|
--- a/src/net/http/server.go
|
|
+++ b/src/net/http/server.go
|
|
@@ -736,9 +736,25 @@ func (cr *connReader) abortPendingRead() {
|
|
}
|
|
cr.aborted = true
|
|
cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
|
|
- for cr.inRead {
|
|
- cr.cond.Wait()
|
|
- }
|
|
+ done := make(chan struct{})
|
|
+ go func() {
|
|
+ for cr.inRead {
|
|
+ cr.cond.Wait()
|
|
+ }
|
|
+ close(done)
|
|
+ }()
|
|
+
|
|
+ func() {
|
|
+ for {
|
|
+ select {
|
|
+ case <-done:
|
|
+ return
|
|
+ case <-time.After(100*time.Millisecond):
|
|
+ cr.conn.rwc.SetReadDeadline(aLongTimeAgo)
|
|
+ }
|
|
+ }
|
|
+ }()
|
|
+
|
|
cr.conn.rwc.SetReadDeadline(time.Time{})
|
|
}
|
|
|
|
--
|
|
2.27.0
|
|
|