Skip to content

Commit

Permalink
Merge pull request #21 from jbenet/fix/race-lock
Browse files Browse the repository at this point in the history
Fix close deadlock
  • Loading branch information
jbenet committed Dec 3, 2015
2 parents f90119e + 6f52ef1 commit f3ab207
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
24 changes: 22 additions & 2 deletions conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ type Conn struct {

closed bool
closeLock sync.Mutex

closing bool
closingLock sync.Mutex
}

func newConn(nconn net.Conn, tconn smux.Conn, s *Swarm) *Conn {
Expand Down Expand Up @@ -115,14 +118,31 @@ func (c *Conn) Streams() []*Stream {
return streams
}

// GoClose spawns off a goroutine to close the connection iff the connection is
// not already being closed and returns immediately
func (c *Conn) GoClose() {
c.closingLock.Lock()
defer c.closingLock.Unlock()
if c.closing {
return
}
c.closing = true

go c.Close()
}

// Close closes this connection
func (c *Conn) Close() error {
c.closeLock.Lock()
defer c.closeLock.Unlock()

if c.closed {
if c.closed == true {
return nil
}

c.closingLock.Lock()
c.closing = true
c.closingLock.Unlock()

c.closed = true

// close streams
Expand Down
2 changes: 1 addition & 1 deletion swarm.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ func (s *Swarm) Conns() []*Conn {
open := make([]*Conn, 0, len(conns))
for _, c := range conns {
if c.smuxConn.IsClosed() {
c.Close()
c.GoClose()
} else {
open = append(open, c)
}
Expand Down

0 comments on commit f3ab207

Please sign in to comment.