File tree Expand file tree Collapse file tree 2 files changed +60
-4
lines changed
Expand file tree Collapse file tree 2 files changed +60
-4
lines changed Original file line number Diff line number Diff line change @@ -140,6 +140,7 @@ func (s *Sender) Start() {
140140 s .done = make (chan struct {})
141141
142142 go func () {
143+ // for range on nil chan is OK
143144 for packet := range s .buf {
144145 s .Output (packet )
145146 }
@@ -148,7 +149,7 @@ func (s *Sender) Start() {
148149}
149150
150151func (s * Sender ) Wait () {
151- if done := s .done ; s . done != nil {
152+ if done := s .done ; done != nil {
152153 <- done
153154 }
154155}
@@ -165,10 +166,12 @@ func (s *Sender) State() string {
165166
166167func (s * Sender ) Close () {
167168 // close buffer if exists
168- if buf := s .buf ; buf != nil {
169- s .buf = nil
170- defer close (buf )
169+ s .mu .Lock ()
170+ if s .buf != nil {
171+ close (s .buf ) // exit from for range loop
172+ s .buf = nil // prevent writing to closed chan
171173 }
174+ s .mu .Unlock ()
172175
173176 s .Node .Close ()
174177}
Original file line number Diff line number Diff line change 1+ package core
2+
3+ import (
4+ "testing"
5+
6+ "github.com/stretchr/testify/require"
7+ )
8+
9+ func TestSenser (t * testing.T ) {
10+ recv := make (chan * Packet ) // blocking receiver
11+
12+ sender := NewSender (nil , & Codec {})
13+ sender .Output = func (packet * Packet ) {
14+ recv <- packet
15+ }
16+ require .Equal (t , "new" , sender .State ())
17+
18+ sender .Start ()
19+ require .Equal (t , "connected" , sender .State ())
20+
21+ sender .Input (& Packet {})
22+ sender .Input (& Packet {})
23+
24+ require .Equal (t , 2 , sender .Packets )
25+ require .Equal (t , 0 , sender .Drops )
26+
27+ // important to read one before close
28+ // because goroutine in Start() can run with nil chan
29+ // it's OK in real life, but bad for test
30+ _ , ok := <- recv
31+ require .True (t , ok )
32+
33+ sender .Close ()
34+ require .Equal (t , "closed" , sender .State ())
35+
36+ sender .Input (& Packet {})
37+
38+ require .Equal (t , 2 , sender .Packets )
39+ require .Equal (t , 1 , sender .Drops )
40+
41+ // read 2nd
42+ _ , ok = <- recv
43+ require .True (t , ok )
44+
45+ // read 3rd
46+ select {
47+ case <- recv :
48+ ok = true
49+ default :
50+ ok = false
51+ }
52+ require .False (t , ok )
53+ }
You can’t perform that action at this time.
0 commit comments