Fix race condition (*tcp.endpoint).Close
Atomically close the endpoint. Before this change, it was possible for multiple callers to perform duplicate work. PiperOrigin-RevId: 300462110
This commit is contained in:
parent
61051f2268
commit
538e35f61b
|
@ -825,6 +825,7 @@ func (e *endpoint) Abort() {
|
||||||
func (e *endpoint) Close() {
|
func (e *endpoint) Close() {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
closed := e.closed
|
closed := e.closed
|
||||||
|
e.closed = true
|
||||||
e.mu.Unlock()
|
e.mu.Unlock()
|
||||||
if closed {
|
if closed {
|
||||||
return
|
return
|
||||||
|
@ -833,13 +834,7 @@ func (e *endpoint) Close() {
|
||||||
// Issue a shutdown so that the peer knows we won't send any more data
|
// Issue a shutdown so that the peer knows we won't send any more data
|
||||||
// if we're connected, or stop accepting if we're listening.
|
// if we're connected, or stop accepting if we're listening.
|
||||||
e.Shutdown(tcpip.ShutdownWrite | tcpip.ShutdownRead)
|
e.Shutdown(tcpip.ShutdownWrite | tcpip.ShutdownRead)
|
||||||
e.closeNoShutdown()
|
|
||||||
}
|
|
||||||
|
|
||||||
// closeNoShutdown closes the endpoint without doing a full shutdown. This is
|
|
||||||
// used when a connection needs to be aborted with a RST and we want to skip
|
|
||||||
// a full 4 way TCP shutdown.
|
|
||||||
func (e *endpoint) closeNoShutdown() {
|
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
|
|
||||||
// For listening sockets, we always release ports inline so that they
|
// For listening sockets, we always release ports inline so that they
|
||||||
|
@ -858,8 +853,6 @@ func (e *endpoint) closeNoShutdown() {
|
||||||
e.boundPortFlags = ports.Flags{}
|
e.boundPortFlags = ports.Flags{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark endpoint as closed.
|
|
||||||
e.closed = true
|
|
||||||
// Either perform the local cleanup or kick the worker to make sure it
|
// Either perform the local cleanup or kick the worker to make sure it
|
||||||
// knows it needs to cleanup.
|
// knows it needs to cleanup.
|
||||||
switch e.EndpointState() {
|
switch e.EndpointState() {
|
||||||
|
|
Loading…
Reference in New Issue