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 @@ -32,6 +32,7 @@ type Conn struct {
32
32
33
33
// handshakeStatus is 1 if the connection is currently transferring
34
34
// application data (i.e. is not currently processing a handshake).
35
+ // handshakeStatus == 1 implies handshakeErr == nil.
35
36
// This field is only to be accessed with sync/atomic.
36
37
handshakeStatus uint32
37
38
// constant after handshake; protected by handshakeMutex
@@ -1396,6 +1397,13 @@ func (c *Conn) HandshakeContext(ctx context.Context) error {
1396
1397
}
1397
1398
1398
1399
func (c * Conn ) handshakeContext (ctx context.Context ) (ret error ) {
1400
+ // Fast sync/atomic-based exit if there is no handshake in flight and the
1401
+ // last one succeeded without an error. Avoids the expensive context setup
1402
+ // and mutex for most Read and Write calls.
1403
+ if c .handshakeComplete () {
1404
+ return nil
1405
+ }
1406
+
1399
1407
handshakeCtx , cancel := context .WithCancel (ctx )
1400
1408
// Note: defer this before starting the "interrupter" goroutine
1401
1409
// so that we can tell the difference between the input being canceled and
@@ -1454,6 +1462,9 @@ func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
1454
1462
if c .handshakeErr == nil && ! c .handshakeComplete () {
1455
1463
c .handshakeErr = errors .New ("tls: internal error: handshake should have had a result" )
1456
1464
}
1465
+ if c .handshakeErr != nil && c .handshakeComplete () {
1466
+ panic ("tls: internal error: handshake returned an error but is marked successful" )
1467
+ }
1457
1468
1458
1469
return c .handshakeErr
1459
1470
}
You can’t perform that action at this time.
0 commit comments