diff options
| author | database64128 <free122448@hotmail.com> | 2025-08-29 17:52:54 +0800 |
|---|---|---|
| committer | Sean Liao <sean@liao.dev> | 2025-09-06 02:20:36 -0700 |
| commit | a6144613d3b601be1db6aa2fdaa79c954fdfe02c (patch) | |
| tree | a32e088ae2df2218d82f695729eba4a23e5be192 /src/crypto/tls | |
| parent | e8126bce9e511b92b914643d30f96846bbc5c783 (diff) | |
| download | go-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/crypto/tls')
| -rw-r--r-- | src/crypto/tls/conn.go | 28 |
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() } }() } |
