Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

Commit

Permalink
fix: handle case where swarm closes before stream
Browse files Browse the repository at this point in the history
When we close a connection, we set the "stream" set to nil to avoid opening new
stream. Unfortunately, this meant we wouldn't decrement the reference count on
the swarm.
  • Loading branch information
Stebalien committed Sep 2, 2020
1 parent 8493980 commit 5217668
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 8 deletions.
4 changes: 1 addition & 3 deletions swarm_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,10 @@ func (c *Conn) doClose() {
}()
}

func (c *Conn) removeStream(s *Stream) bool {
func (c *Conn) removeStream(s *Stream) {
c.streams.Lock()
_, has := c.streams.m[s]
delete(c.streams.m, s)
c.streams.Unlock()
return has
}

// listens for new streams.
Expand Down
10 changes: 5 additions & 5 deletions swarm_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type Stream struct {
stream mux.MuxedStream
conn *Conn

closeOnce sync.Once

notifyLk sync.Mutex

protocol atomic.Value
Expand Down Expand Up @@ -76,15 +78,15 @@ func (s *Stream) Write(p []byte) (int, error) {
// resources.
func (s *Stream) Close() error {
err := s.stream.Close()
s.remove()
s.closeOnce.Do(s.remove)
return err
}

// Reset resets the stream, signaling an error on both ends and freeing all
// associated resources.
func (s *Stream) Reset() error {
err := s.stream.Reset()
s.remove()
s.closeOnce.Do(s.remove)
return err
}

Expand All @@ -102,9 +104,7 @@ func (s *Stream) CloseRead() error {
}

func (s *Stream) remove() {
if !s.conn.removeStream(s) {
return
}
s.conn.removeStream(s)

// We *must* do this in a goroutine. This can be called during a
// an open notification and will block until that notification is done.
Expand Down
17 changes: 17 additions & 0 deletions swarm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -440,3 +440,20 @@ func TestNoDial(t *testing.T) {
t.Fatal("should have failed with ErrNoConn")
}
}

func TestCloseWithOpenStreams(t *testing.T) {
ctx := context.Background()
swarms := makeSwarms(ctx, t, 2)
connectSwarms(t, ctx, swarms)

s, err := swarms[0].NewStream(ctx, swarms[1].LocalPeer())
if err != nil {
t.Fatal(err)
}
defer s.Close()
// close swarm before stream.
err = swarms[0].Close()
if err != nil {
t.Fatal(err)
}
}

0 comments on commit 5217668

Please sign in to comment.