mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
e8126bce9e
commit
a6144613d3
1 changed files with 7 additions and 21 deletions
|
|
@ -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()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue