Index: src/pkg/crypto/tls/conn.go |
=================================================================== |
--- a/src/pkg/crypto/tls/conn.go |
+++ b/src/pkg/crypto/tls/conn.go |
@@ -44,8 +44,7 @@ |
clientProtocolFallback bool |
// first permanent error |
- errMutex sync.Mutex |
- err error |
+ connErr |
// input/output |
in, out halfConn // in.Mutex < out.Mutex |
@@ -56,21 +55,25 @@ |
tmp [16]byte |
} |
-func (c *Conn) setError(err error) error { |
- c.errMutex.Lock() |
- defer c.errMutex.Unlock() |
+type connErr struct { |
+ mu sync.Mutex |
+ value error |
+} |
- if c.err == nil { |
- c.err = err |
+func (e *connErr) setError(err error) error { |
+ e.mu.Lock() |
+ defer e.mu.Unlock() |
+ |
+ if e.value == nil { |
+ e.value = err |
} |
return err |
} |
-func (c *Conn) error() error { |
- c.errMutex.Lock() |
- defer c.errMutex.Unlock() |
- |
- return c.err |
+func (e *connErr) error() error { |
+ e.mu.Lock() |
+ defer e.mu.Unlock() |
+ return e.value |
} |
// Access to net.Conn methods. |
@@ -660,8 +663,7 @@ |
c.tmp[0] = alertLevelError |
c.tmp[1] = byte(err.(alert)) |
c.writeRecord(recordTypeAlert, c.tmp[0:2]) |
- c.err = &net.OpError{Op: "local error", Err: err} |
- return n, c.err |
+ return n, c.setError(&net.OpError{Op: "local error", Err: err}) |
} |
} |
return |
@@ -672,8 +674,8 @@ |
// c.in.Mutex < L; c.out.Mutex < L. |
func (c *Conn) readHandshake() (interface{}, error) { |
for c.hand.Len() < 4 { |
- if c.err != nil { |
- return nil, c.err |
+ if err := c.error(); err != nil { |
+ return nil, err |
} |
if err := c.readRecord(recordTypeHandshake); err != nil { |
return nil, err |
@@ -684,11 +686,11 @@ |
n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) |
if n > maxHandshake { |
c.sendAlert(alertInternalError) |
- return nil, c.err |
+ return nil, c.error() |
} |
for c.hand.Len() < 4+n { |
- if c.err != nil { |
- return nil, c.err |
+ if err := c.error(); err != nil { |
+ return nil, err |
} |
if err := c.readRecord(recordTypeHandshake); err != nil { |
return nil, err |
@@ -738,12 +740,12 @@ |
// Write writes data to the connection. |
func (c *Conn) Write(b []byte) (int, error) { |
- if c.err != nil { |
- return 0, c.err |
+ if err := c.error(); err != nil { |
+ return 0, err |
} |
- if c.err = c.Handshake(); c.err != nil { |
- return 0, c.err |
+ if err := c.Handshake(); err != nil { |
+ return 0, c.setError(err) |
} |
c.out.Lock() |
@@ -753,9 +755,8 @@ |
return 0, alertInternalError |
} |
- var n int |
- n, c.err = c.writeRecord(recordTypeApplicationData, b) |
- return n, c.err |
+ n, err := c.writeRecord(recordTypeApplicationData, b) |
+ return n, c.setError(err) |
} |
// Read can be made to time out and return a net.Error with Timeout() == true |
@@ -768,14 +769,14 @@ |
c.in.Lock() |
defer c.in.Unlock() |
- for c.input == nil && c.err == nil { |
+ for c.input == nil && c.error() == nil { |
if err := c.readRecord(recordTypeApplicationData); err != nil { |
// Soft error, like EAGAIN |
return 0, err |
} |
} |
- if c.err != nil { |
- return 0, c.err |
+ if err := c.error(); err != nil { |
+ return 0, err |
} |
n, err = c.input.Read(b) |
if c.input.off >= len(c.input.data) { |