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() {
|
||||
e.mu.Lock()
|
||||
closed := e.closed
|
||||
e.closed = true
|
||||
e.mu.Unlock()
|
||||
if closed {
|
||||
return
|
||||
|
@ -833,13 +834,7 @@ func (e *endpoint) Close() {
|
|||
// 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.
|
||||
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()
|
||||
|
||||
// For listening sockets, we always release ports inline so that they
|
||||
|
@ -858,8 +853,6 @@ func (e *endpoint) closeNoShutdown() {
|
|||
e.boundPortFlags = ports.Flags{}
|
||||
}
|
||||
|
||||
// Mark endpoint as closed.
|
||||
e.closed = true
|
||||
// Either perform the local cleanup or kick the worker to make sure it
|
||||
// knows it needs to cleanup.
|
||||
switch e.EndpointState() {
|
||||
|
|
Loading…
Reference in New Issue