Skip to content
Snippets Groups Projects
Commit a0558b8f authored by Tamir Duberstein's avatar Tamir Duberstein Committed by Jim Beveridge
Browse files

[netstack] be more careful about double-closing

I haven't yet been able to reproduce this in a test.

Cherry-picked for 20190206_00_RC01

NET-2077

Test: None
Change-Id: I138e10c8c21f38567d83185dfb84f6b49014439c
parent 697c1992
No related branches found
No related tags found
No related merge requests found
......@@ -328,15 +328,11 @@ func (ios *iostate) loopRead() error {
}
func (ios *iostate) loopControl() error {
synthesizeClose := true
defer func() {
if synthesizeClose {
if code, err := ios.Close(); err != nil {
log.Printf("synethsize close failed: %s", err)
} else if code != 0 {
log.Printf("synethsize close failed: %s", syscall.Errno(code))
}
if code, err := ios.Close(); err != nil {
log.Printf("SocketControl.Close failed: %s", err)
} else if code != 0 {
log.Printf("SocketControl.Close failed: %s", syscall.Errno(code))
}
if err := ios.dataHandle.Close(); err != nil {
......@@ -394,7 +390,6 @@ func (ios *iostate) loopControl() error {
case obs&zx.SignalSocketControlReadable != 0:
continue
case obs&LOCAL_SIGNAL_CLOSING != 0:
synthesizeClose = false
return nil
case obs&zx.SignalSocketPeerClosed != 0:
return nil
......@@ -721,21 +716,27 @@ func decodeAddr(addr []uint8) (tcpip.FullAddress, error) {
}
func (ios *iostate) Close() (int16, error) {
// Signal that we're about to close. This tells the various message loops to finish
// processing, and let us know when they're done.
if err := ios.dataHandle.Handle().Signal(0, LOCAL_SIGNAL_CLOSING); err != nil {
panic(err)
}
select {
case <-ios.closing:
// Don't double close the channel.
default:
// Signal that we're about to close. This tells the various message loops to finish
// processing, and let us know when they're done.
if err := ios.dataHandle.Handle().Signal(0, LOCAL_SIGNAL_CLOSING); err != nil {
panic(err)
}
close(ios.closing)
if ios.loopWriteDone != nil {
<-ios.loopWriteDone
}
close(ios.closing)
ios.ep.Close()
if ios.loopWriteDone != nil {
<-ios.loopWriteDone
}
// NB: we can't wait for loopRead to finish here because the dataHandle
// may be full, and loopRead will never exit.
ios.ep.Close()
// NB: we can't wait for loopRead to finish here because the dataHandle
// may be full, and loopRead will never exit.
}
return 0, nil
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment