aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordatabase64128 <free122448@hotmail.com>2025-08-29 17:52:54 +0800
committerSean Liao <sean@liao.dev>2025-09-06 02:20:36 -0700
commita6144613d3b601be1db6aa2fdaa79c954fdfe02c (patch)
treea32e088ae2df2218d82f695729eba4a23e5be192 /src
parente8126bce9e511b92b914643d30f96846bbc5c783 (diff)
downloadgo-a6144613d3b601be1db6aa2fdaa79c954fdfe02c.tar.xz
crypto/tls: use context.AfterFunc in handshakeContext
This saves a goroutine when ctx can be canceled but is not canceled during the handshakeContext call. Use ctx consistently, because in this path (c.quic == nil) handshakeCtx will only be canceled when ctx is canceled. Change-Id: I7f4565119f30d589dce026b0d7ef3c324220525a Reviewed-on: https://go-review.googlesource.com/c/go/+/699895 Reviewed-by: Roland Shoemaker <roland@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> Reviewed-by: Michael Pratt <mpratt@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/crypto/tls/conn.go28
1 files changed, 7 insertions, 21 deletions
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
index b36fcaa648..d4d68c0744 100644
--- a/src/crypto/tls/conn.go
+++ b/src/crypto/tls/conn.go
@@ -1524,7 +1524,7 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
}
handshakeCtx, cancel := context.WithCancel(ctx)
- // Note: defer this before starting the "interrupter" goroutine
+ // Note: defer this before calling context.AfterFunc
// so that we can tell the difference between the input being canceled and
// this cancellation. In the former case, we need to close the connection.
defer cancel()
@@ -1533,28 +1533,14 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
c.quic.cancelc = handshakeCtx.Done()
c.quic.cancel = cancel
} else if ctx.Done() != nil {
- // Start the "interrupter" goroutine, if this context might be canceled.
- // (The background context cannot).
- //
- // The interrupter goroutine waits for the input context to be done and
- // closes the connection if this happens before the function returns.
- done := make(chan struct{})
- interruptRes := make(chan error, 1)
+ // Close the connection if ctx is canceled before the function returns.
+ stop := context.AfterFunc(ctx, func() {
+ _ = c.conn.Close()
+ })
defer func() {
- close(done)
- if ctxErr := <-interruptRes; ctxErr != nil {
+ if !stop() {
// Return context error to user.
- ret = ctxErr
- }
- }()
- go func() {
- select {
- case <-handshakeCtx.Done():
- // Close the connection, discarding the error
- _ = c.conn.Close()
- interruptRes <- handshakeCtx.Err()
- case <-done:
- interruptRes <- nil
+ ret = ctx.Err()
}
}()
}