File tree 1 file changed +11
-0
lines changed
1 file changed +11
-0
lines changed Original file line number Diff line number Diff line change @@ -36,6 +36,7 @@ type Conn struct {
36
36
37
37
// handshakeStatus is 1 if the connection is currently transferring
38
38
// application data (i.e. is not currently processing a handshake).
39
+ // handshakeStatus == 1 implies handshakeErr == nil.
39
40
// This field is only to be accessed with sync/atomic.
40
41
handshakeStatus uint32
41
42
// constant after handshake; protected by handshakeMutex
@@ -1681,6 +1682,13 @@ func (c *Conn) HandshakeContext(ctx context.Context) error {
1681
1682
}
1682
1683
1683
1684
func (c * Conn ) handshakeContext (ctx context.Context ) (ret error ) {
1685
+ // Fast sync/atomic-based exit if there is no handshake in flight and the
1686
+ // last one succeeded without an error. Avoids the expensive context setup
1687
+ // and mutex for most Read and Write calls.
1688
+ if c .handshakeComplete () {
1689
+ return nil
1690
+ }
1691
+
1684
1692
handshakeCtx , cancel := context .WithCancel (ctx )
1685
1693
// Note: defer this before starting the "interrupter" goroutine
1686
1694
// so that we can tell the difference between the input being canceled and
@@ -1739,6 +1747,9 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
1739
1747
if c .handshakeErr == nil && ! c .handshakeComplete () {
1740
1748
c .handshakeErr = errors .New ("tls: internal error: handshake should have had a result" )
1741
1749
}
1750
+ if c .handshakeErr != nil && c .handshakeComplete () {
1751
+ panic ("tls: internal error: handshake returned an error but is marked successful" )
1752
+ }
1742
1753
1743
1754
return c .handshakeErr
1744
1755
}
You can’t perform that action at this time.
0 commit comments