Close closes the connection.
()
| 1587 | |
| 1588 | // Close closes the connection. |
| 1589 | func (c *Conn) Close() error { |
| 1590 | |
| 1591 | if c.DirectOut { |
| 1592 | return c.conn.Close() |
| 1593 | } |
| 1594 | // Interlock with Conn.Write above. |
| 1595 | var x int32 |
| 1596 | for { |
| 1597 | x = atomic.LoadInt32(&c.activeCall) |
| 1598 | if x&1 != 0 { |
| 1599 | return net.ErrClosed |
| 1600 | } |
| 1601 | if atomic.CompareAndSwapInt32(&c.activeCall, x, x|1) { |
| 1602 | break |
| 1603 | } |
| 1604 | } |
| 1605 | if x != 0 { |
| 1606 | // io.Writer and io.Closer should not be used concurrently. |
| 1607 | // If Close is called while a Write is currently in-flight, |
| 1608 | // interpret that as a sign that this Close is really just |
| 1609 | // being used to break the Write and/or clean up resources and |
| 1610 | // avoid sending the alertCloseNotify, which may block |
| 1611 | // waiting on handshakeMutex or the c.out mutex. |
| 1612 | return c.conn.Close() |
| 1613 | } |
| 1614 | |
| 1615 | var alertErr error |
| 1616 | if c.handshakeComplete() { |
| 1617 | if err := c.closeNotify(); err != nil { |
| 1618 | alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err) |
| 1619 | } |
| 1620 | } |
| 1621 | |
| 1622 | if err := c.conn.Close(); err != nil { |
| 1623 | return err |
| 1624 | } |
| 1625 | return alertErr |
| 1626 | } |
| 1627 | |
| 1628 | var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete") |
| 1629 |
no test coverage detected